Layout of Text in Components - codenameone

I have a couple of questions on text layout in Codenameone I can't seem to find answers to in the docs, videos or forums.
Is it possible to break, wrap text into multiple lines based on the text, such as a newline "\n", or can this only be done by creating a label for each line.
Also is it possible to rotate buttons / labels by 90 degrees, so that text is rotated, I see graphics can be rotated but not sure about how to do for components or text within them.
Any hints of tips would be appreciated. Thanks

Use Spanlabel for multiline label
Use the following code to rotate a button
public class RotatedButton extends Button {
#Override
public void paint(Graphics g) {
g.rotate((float)(Math.PI/4.0), getAbsoluteX(), getAbsoluteY());
super.paint(g);
g.resetAffine();
}
}
RotatedButton btn = new RotatedButton();
btn.setText("Hi");

Related

Changing the bitmap shown in a PictureBox for different TrackBar values

I'm trying to use a TrackBar to control the image that is show in a PictureBox. There are 4 values for the TrackBar (0-4) and four images. The TrackBar's default value is 0 and currently I have set the Background image property to the image I would like to represent the 0 value (not sure if this is even the correct way to start).
so far i'v tried:
private void TrackBar1_Scroll(object sender, EventArgs e)
{
if (TrackBar1.Value == 1)
{
PictureBox1.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.Image2))
}
}
but this hasn't worked. I've got all the relevant images in the resources file all saved as bitmaps...
Any help would be greatly appreciated, still learning the ropes
Thanks
Harry
Not to worry I solved it myself, the code I had used worked, I'd just forgotten to update the scroll event property to the TrackBar1_Scroll Event

Jfree chart Find Subplot

This may sound very basic as a question, but i am stuck in JFreechart use.
Let me lay out my problem :
I have a CombinedDomainXYPlot to which I add my subplots as and when required.
I have used my custom JPopup menu and have included a menu item that is intended to provide user the facility to delete a particular subplot
I am assuming that one can find a subplot using findSubplot method of the main plot. I am able to get mouse positions but not able to do anything with PlotRenderingInfo that's required as input.
Would appreciate some help.
You can get a List of subplots using getSubplots(). To learn which subplot was clicked, examine the ChartMouseEvent that was sent from the ChartPanel, as suggested here.
Addendum: Here's a simple implementation of ChartMouseListener that will show each ChartEntity as it is clicked.
ChartPanel panel = ...
panel.addChartMouseListener(new ChartMouseListener() {
#Override
public void chartMouseClicked(ChartMouseEvent e) {
System.out.println(e.getEntity().getClass());
}
#Override
public void chartMouseMoved(ChartMouseEvent event) {}
});

How to make label transparent without any flickering at load time

I have a panel and on that I've a picturebox. There are around 20 labels that I've to show in the panel. I want the background of Label to be transparent ie the image in picturebox is shown and the label displays only the text.
Now since labels do not exhibit true transparency I made the labels child of picturebox
this.lbl1.Parent = pictureBox1;
This has solved my immediate problem but now when the form loads, all the labels take a while to become visible and do so one at a time. I'd appreciate if you guys can give some solution for this.
Thanks in advance
The standard cure for flicker is double-buffering. But that cannot solve this kind of flicker. It is a different kind, caused by having multiple windows overlapping each other. Each label is its own window. When the form needs to paint itself, it draws its background leaving holes for the child windows. Each child window then takes a turn drawing itself. And their child windows draw themselves next. Etcetera.
This becomes noticeable when one control takes a while to draw, no doubt your picture box. Especially when it displays a large image that needs to be resized. The holes for the child windows stay unpainted while the picture box draws. They have a white background, black when you use the form's TransparencyKey or Opacity property. This can contrast badly with the image in your picture box, that effect is perceived by the user as flicker.
One immediate cure is to not use controls so you don't pay for their window. A Label is very convenient but it is a massive waste of system resources to burn up a window just to display a string. You can simply implement the picture box' Paint event and draw the strings with TextRenderer.DrawText(). PictureBox has double-buffering turned on by default so the image as well as the text is drawn completely smoothly, no more flicker. The obvious disadvantage is that you lose the convenience of point-and-click, you have to write code.
There are other fixes possible. One of them is to prevent the picture box from leaving holes for the child windows. It will draw the entire image, the labels pop on top of them. That's still flicker but not nearly as noticeable. Add a new class to your project and paste this code:
using System;
using System.Windows.Forms;
internal class MyPictureBox : PictureBox {
protected override CreateParams CreateParams {
get {
var parms = base.CreateParams;
parms.Style &= ~0x02000000; // Turn off WS_CLIPCHILDREN
return parms;
}
}
}
Compile and drop the new picture box control from the top of the toolbox onto your form.
Yet another possible workaround is to make the form and all of its children double-buffered. This doesn't speed up the painting at all but all of the windows get rendered into a memory buffer, the result is blitted to the screen. You'll notice a delay but the window suddenly pops on the screen. This is called compositing. Winforms doesn't support this directly since it can have side-effects but it is easy to enable. Paste this code into your form class:
protected override CreateParams CreateParams {
get {
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
Supported by XP and later. Watch out for painting artifacts.
or you can ditch the labels and draw the text yourself:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
TextRenderer.DrawText(e.Graphics, "Label1", SystemFonts.DefaultFont,
new Point(10, 10), Color.Black, Color.Empty);
}
The label does not support transparency, you must create your own unique custom control, you can see these code examples.
http://www.codeproject.com/KB/dotnet/transparent_controls_net.aspx http://www.codeproject.com/KB/vb/uLabelX.aspx
Bye

How can I create a line in a WinForms Application?

I want to create a simple 3D line in a WinForms application to improve visual arrangement of my form layout.
This line is exacly like the line in About Windows dialog (can be opened in Windows Explorer -> Help -> About Windows).
An example be checked
The last line (3D) is the one I want, not the first one.
How can this be done in C# or Visual Basic (.NET)?
Add a Label control with a 3D border and with no text then set the height to 2.
var separator = new Label();
separator.BorderStyle = BorderStyle.Fixed3D;
separator.Height = 2;
If you use SysInternals' ZoomIt utility, you can see that this is simply two lines. A dark gray one above a white one. Drawing lines is simple enough with Graphics.DrawLine(), you just need to make sure you pick a dark color that work well with the form's BackColor. That isn't always battleship gray if the user selected another theme. Which makes the GroupBox trick fall flat.
This sample code is serviceable:
protected override void OnPaint(PaintEventArgs e) {
Color back = this.BackColor;
Color dark = Color.FromArgb(back.R >> 1, back.G >> 1, back.B >> 1);
int y = button1.Bottom + 20;
using (var pen = new Pen(dark)) {
e.Graphics.DrawLine(pen, 30, y, this.ClientSize.Width - 30, y);
}
e.Graphics.DrawLine(Pens.White, 30, y+1, this.ClientSize.Width - 30, y+1);
}
Note the use of button1 in this code, there to make sure the line is drawn at the right height, even when the form is rescaled. Pick your own control as a reference for the line.
One way is to create a group box with no label and height 0 (or is it 1, don't quite remember) - I know I've used that trick before, even if it feels a bit hacky :-)
I too have used the GroupBox hack and it's got the benefit of styling itself based on the OS border theme.
There is also a Line class in the VB Power Packs control collection. There's a few other goodies in there that we've used too.
Edit: Here's my Seperator class for drawing horizontal line using the method mentioned above.
public class Separator : GroupBox
{
// Methods
protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
{
base.SetBoundsCore(x, y, width, 3, specified);
}
// Properties
[DefaultValue("")]
public override string Text
{
get
{
return string.Empty;
}
set
{
}
}
}
You can get a line separator effect by adding a Label and setting its text as underscores "_"
I wrote a custom control just for this purpose. You can install the control suite from from NuGet:
Install-Package ALMSTWKND -Version 1.0.0
After installation, it will be added to the Toolbox pane.

Paragraph formatting in a WPF RichTextBox?

I need to apply paragraph formatting to a selection in a rich text box. My RTB will behave the same way as the rich text boxes on StackOverflow--the user can type text into the RTB, but they can also enter code blocks. The RTB will apply very simple formatting to the code block--it will change the font and apply a background color to the entire block, similar to what you see in the code block below.
Changing the font is pretty straightforward:
var textRange = new TextRange(rtb.Selection.Start, rtb.Selection.End);
textRange.ApplyPropertyValue(TextElement.FontFamilyProperty, "Consolas");
textRange.ApplyPropertyValue(TextElement.FontSizeProperty, 10D );
Now I need to apply some paragraph-level formatting. I need to set the paragraph margin to 0, so I don't get a blank line between code lines, and I need to set the paragraph background color. Here's my problem: I can't figure out how to get the paragraph elements from the selection, so that I can apply formatting.
Any suggestions? An example of how to apply the Margin and Background properties would be incredibly helpful. Thanks!
Oh, that was easy.. Came across the answer with a little more research:
var textRange = new TextRange(TextBox.Selection.Start, TextBox.Selection.End);
textRange.ApplyPropertyValue(TextElement.FontFamilyProperty, "Consolas");
textRange.ApplyPropertyValue(TextElement.FontSizeProperty, 10D );
textRange.ApplyPropertyValue(Paragraph.MarginProperty, new Thickness(0));
textRange.ApplyPropertyValue(Paragraph.BackgroundProperty, "LightSteelBlue");
The only limitation is that the highlighting still extends only as far as the text, rather than to the right side of the control. I'll leave this question open for a couple of days; if someone can tell me how to extend the background to the right edge of the control, I'll accept your answer to this question.

Resources