The problem with the layout of checkbox when using BooleanFieldEditor - eclipse-plugin

I am trying to use BooleanFieldEditor instead of Button with style SWT.CHECK. And I am getting the problem with layout of the checkbox.
The significant part of my previous code is:
Composite projectGroup = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout();
layout.numColumns = 1;
projectGroup.setLayout(layout);
projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
Button checkBox = new Button(projectGroup, SWT.CHECK);
checkBox.setText(Messages.getString("WizardNewProjectCreationPage.createEmptyProject")); //$NON-NLS-1$
checkBox.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent event) {
Button button = (Button) event.getSource();
shouldEmptyProjectBeCreated = button.getSelection();
}
});
It gives me this result:
In this case the checkbox has a small indent at the top and the left side.
The significant part of my current code is:
Composite projectGroup = new Composite(parent, SWT.NONE);
GridLayoutFactory.fillDefaults().extendedMargins(100, 0, 100, 0).spacing(100, 100).applyTo(projectGroup);
BooleanFieldEditor emptyProjectCheckbox = new BooleanFieldEditor("createEmptyProject",
Messages.getString("WizardNewProjectCreationPage.createEmptyProject"), projectGroup);
// GridDataFactory.defaultsFor(projectGroup).grab(true, false).span(2, 1).applyTo(projectGroup);
// emptyProjectCheckbox.fillIntoGrid(projectGroup, 1);
createEmptyProject = emptyProjectCheckbox.getBooleanValue();
Whatever values I set into extendedMargins() and spacing() methods, the result is the same - checkbox is located strictly at the level of the upper frame:
As you can see, in this case indents are smaller than on the first picture. I want to make the same indents as on the first image and want to understand, how to manage the location of BooleanFieldEditor's checkbox relatively to another elements.

Using second composite solves the problem:
Composite projectGroup = new Composite(parent, SWT.NONE);
GridLayoutFactory.fillDefaults().extendedMargins(5, 0, 5, 0).applyTo(projectGroup);
//intermediate composite, which needs to work around the problem with layout of checkbox of BooleanFieldEditor
Composite intermediateComposite = new Composite(projectGroup, SWT.NONE);
BooleanFieldEditor emptyProjectCheckbox = new BooleanFieldEditor("createEmptyProject",
Messages.getString("WizardNewProjectCreationPage.createEmptyProject"), intermediateComposite);
createEmptyProject = emptyProjectCheckbox.getBooleanValue();

Related

Codename One Drag & Drop blackens dialog background

I'm developing an app that uses drag & drop operations. The drag & drop part includes four containers as drop targets and two draggable labels.
The app works as expected in the simulator, but when I install it on my Android phone, the background of the dialog (otherwise white) turns black for a swift moment as soon as the draggable components (labels) are released (then gets back to the original light color).
In the theme builder, I have set the background of the dialog to an almost white color (unselected, selected, pressed, disabled), but that doesn't show any effect.
Is there any turnaround to keep the background color stable? Any help would be appreciated.
Here is the relevant code excerpt:
Dialog dialog_W1 = new Dialog();
dialog_W1.setScrollableY(true);
dialog_W1.setLayout(new BoxLayout(2));
dialog_W1.setScrollableY(true);
dialog_W1.setTitle("Acerte o bichinho");
Image img_Cat = Image.createImage("/cat.png");
ScaleImageLabel label_Scaled_Image = new ScaleImageLabel(img_Cat);
label_Scaled_Image.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FIT);
label_Scaled_Image.setUIID("NewLabel");
Label label_1 = new Label("ga");
Label label_2 = new Label("to");
label_1.setUIID("LabelWord");
label_2.setUIID("LabelWord");
label_1.setDraggable(true);
label_2.setDraggable(true);
Container c_1 = new Container();
Container c_2 = new Container();
Container c_3 = new Container();
Container c_4 = new Container();
c_1.setDropTarget(true);
c_2.setDropTarget(true);
c_3.setDropTarget(true);
c_4.setDropTarget(true);
c_1.setLayout(new BoxLayout(2));
c_2.setLayout(new BoxLayout(2));
c_3.setLayout(new BoxLayout(2));
c_4.setLayout(new BoxLayout(2));
c_1.setUIID("Container_1");
c_2.setUIID("Container_1");
c_3.setUIID("Container_2");
c_4.setUIID("Container_2");
c_3.add(label_2);
c_4.add(label_1);
GridLayout gl = new GridLayout(2,2);
Container container_0 = new Container(gl);
container_0.add(c_1);
container_0.add(c_2);
container_0.add(c_3);
container_0.add(c_4);
ArrayList <Container> list_Containers = new ArrayList<>();
list_Containers.add(c_1);
list_Containers.add(c_2);
list_Containers.add(c_3);
list_Containers.add(c_4);
ArrayList <Label> list_Labels = new ArrayList<>();
list_Labels.add(label_1);
list_Labels.add(label_2);
for (Label label : list_Labels) {
label.addDragOverListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
for (Container c : list_Containers) {
int int_C = c.getComponentCount();
if (int_C == 1) {
c.setDropTarget(false);
} else if (int_C == 0) {
c.setDropTarget(true);
}
}
}
});
}
I suggest showing the Dialog as a modless dialog instead of using the show method use showModless() or similar.
Odd things like this can happen because of the EDT nesting inherent in modal dialogs, normally we don't recommend using dialog for anything more than simple notifications. When we use drag and drop from a dialog like component we use InteractionDialog.

Horizontal scrollbar updating

I was messing around with SWT (for a PropertyPage), and found a little 'bug'?
Basically, when I resize the shell so it is smaller than my controls, it will make a scrollBar visible, which works just as intended. Though if I resize my controls (which are all children of a single root of course), somehow one or more parents don't get updated of the change which results in some weird behavior.
When my controls grow in size, it basically grows out of the shell (not visible) while there is no Scrollbar made visible. If I resize the shell (smaller than the initial size), the ScrollBar will become visible, but only for the initial size instead of the full width.
When my controls shrink in size it won't 'pack' either parent, which means I can scroll beyond the reach of my controls into emptiness.
Maybe it's worth mentioning that for me only horizontal growing/shrinking is a problem, although I'm pretty sure the same problems are occurring for vertical resizing
My question was if there is a solution/workaround for this. I have tried calling Layout() and pack() on various parents and the shell itself, without success. Now I know there is a custom (sadly private) Layout type used by one of the parents of a property page (the PreferenceDialog#PageLayout). Maybe this behavior comes this implementation?
EDIT: on request an MCVE
I assume one knows how to setup for a propertyPage, so for the sake of clarity I have posted only the createContents method (overriden from org.eclipse.jface.preference.PreferencePage), and a few helper methods/fields which should recreate a setup where this behavior can be observed. Basically play around with hiding/unhiding columns, and make sure to re-open when you want a different initial childSize (to test both growing and shrinking)
// static so you can re-open a the property/preference page for different initial sizes.
private static boolean h1 = false;
private static boolean h2 = false;
private static boolean h3 = false;
private static boolean h4 = false;
private Composite root;
#Override
protected Control createContents(Composite parent)
{
// setup root
this.root = new Composite(parent, SWT.NONE);
this.root.setLayout(new GridLayout());
this.root.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, false, false));
Table table = new Table(this.root, SWT.SINGLE | SWT.VIRTUAL | SWT.BORDER | SWT.FULL_SELECTION);
table.setHeaderVisible(true);
table.setLinesVisible(true);
table.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, false, false));
TableColumn c1 = new TableColumn(table, SWT.LEFT);
c1.setMoveable(true);
c1.setText("column 1");
this.updateColumn(c1, h1);
TableColumn c2 = new TableColumn(table, SWT.LEFT);
c2.setMoveable(true);
c2.setText("column 2");
this.updateColumn(c2, h2);
TableColumn c3 = new TableColumn(table, SWT.LEFT);
c3.setMoveable(true);
c3.setText("column 3");
this.updateColumn(c3, h3);
TableColumn c4 = new TableColumn(table, SWT.LEFT);
c4.setMoveable(true);
c4.setText("column 4");
this.updateColumn(c4, h4);
Button hide1 = new Button(this.root, SWT.PUSH);
hide1.setText("Hide column 1");
hide1.addListener(SWT.Selection, E -> {
this.updateColumn(c1, h1 = !h1);
this.resize();
});
Button hide2 = new Button(this.root, SWT.PUSH);
hide2.setText("Hide column 2");
hide2.addListener(SWT.Selection, E -> {
this.updateColumn(c2, h2 = !h2);
this.resize();
});
Button hide3 = new Button(this.root, SWT.NONE);
hide3.setText("Hide column 3");
hide3.addListener(SWT.Selection, E -> {
this.updateColumn(c3, h3 = !h3);
this.resize();
});
Button hide4 = new Button(this.root, SWT.PUSH);
hide4.setText("Hide column 4");
hide4.addListener(SWT.Selection, E -> {
this.updateColumn(c4, h4 = !h4);
this.resize();
});
for(int i = 0; i < 20; i++)
{
TableItem ti = new TableItem(table, SWT.NONE);
ti.setText(new String[] {"c1:" + i, "c2:" + i, "c3" + i, "c4" + i});
}
return root;
}
protected void updateColumn(TableColumn c, boolean hide)
{
if(hide)
{
c.setResizable(false);
c.setWidth(0);
}
else
{
c.setResizable(true);
c.setWidth(300);
}
}
protected void resize()
{
this.root.getDisplay().asyncExec(() -> this.root.getShell().layout(null, SWT.ALL | SWT.CHANGED));
}

Keep Anchored Buttons Below Autosized Label

I have a Windows form with an image, a label that contains an error message, and a "Close" button:
The error message could be very short or very long depending on what the error is. When it's long, I want the window to grow in height to display the whole message. Using the label's Anchor and MaximumSize properties and the form's AutoSize property, I was able to get the Label to expand to the maximum width and then expand vertically until the message is displayed. Setting the button's Anchor property to Bottom, Right locks the button to the bottom right corner as intended but the form only expands far enough to display the label and not enough for the button too. So the button is displayed behind the label and can't be seen:
I'd like to know how I can stretch the form to fully contain the text of the label and still leave room at the bottom for the anchored button to produce something like this:
Add 3 panels to your form docked left, bottom and fill. Set the properties as indicated in the image below.
Then set the Label's maximum width to a fixed value in the properties or you can calculate it at run-time:
Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
Me.Label1.MaximumSize = New Size(Me.panelFill.Width, 0)
End Sub
The easiest way is to build the layout with 3 docked panels, like this (hope you can adjust for your needs):
using System;
using System.Drawing;
using System.Windows.Forms;
namespace Samples
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var form = new Form { Padding = new Padding(8), AutoSizeMode = AutoSizeMode.GrowAndShrink, AutoSize = true, Font = new Font("Consolas", 9, FontStyle.Bold) };
var contentPanel = new Panel { Dock = DockStyle.Fill, Parent = form, AutoSizeMode = AutoSizeMode.GrowAndShrink, AutoSize = true };
var imagePanel = new Panel { Dock = DockStyle.Left, Parent = form };
var buttonPanel = new Panel { Dock = DockStyle.Bottom, Parent = form };
var image = new PictureBox { BackColor = Color.Red, Width = 32, Height = 32, Parent = imagePanel };
imagePanel.Width = image.Width + 8;
var button = new Button { Top = 8, AutoSize = true, BackColor = Color.Green, ForeColor = Color.White, Text = "Test", Parent = buttonPanel };
button.Left = buttonPanel.DisplayRectangle.Right - button.Width;
buttonPanel.Height = button.Height + 8;
button.Anchor = AnchorStyles.Right | AnchorStyles.Bottom;
var label = new Label { Dock = DockStyle.Fill, BackColor = Color.Blue, ForeColor = Color.White, MaximumSize = new Size(300, 0), AutoSize = true, Parent = contentPanel };
label.Text = #"The error message could be very short or very long depending on what the error is. When it's long, I want the window to grow in height to display the whole message. Using the label's Anchor and MaximumSize properties and the form's AutoSize property, I was able to get the Label to expand to the maximum width and then expand vertically until the message is displayed. Setting the button's Anchor property to Bottom, Right locks the button to the bottom right corner as intended but the form only expands far enough to display the label and not enough for the button too. So the button is displayed behind the label and can't be seen:";
Application.Run(form);
}
}
}
Result:

Why does the last JLabel I add to the JFrame move if I resize the window by dragging the corner with the mouse?

When I run this program, the panel with the 6 buttons appears as it should on the bottom of the screen, and the first 3 labels appear as they should and where they should, but the last label appears at about the center of the screen. Furthermore, when I click and drag on the bottom right corner of the window (resizing the window), the panel and the last label move so they stay in their relative positions with the size of the window but the first 3 labels stay in their designated positions. When I uncomment the line of code towards the bottom that adds a blank JLabel, all 4 labels are now in their correct spots and only the panel moves when I resize the window. Could someone please explain what is going on here? Thanks in advance!
import javax.swing.*;
import java.awt.*;
public class X extends JFrame{
private JPanel panel;
private JButton buttons[];
private JLabel labels[];
private Icon images[];
public X()
{
panel = new JPanel();
panel.setPreferredSize(new Dimension(470,110));
buttons = new JButton[6];
labels = new JLabel[4];
Dimension dim = new Dimension(75,100);
labels = new JLabel[4];
images = new Icon[6];
for(int i = 0; i<6;i++)
images[i] = new ImageIcon(getClass().getResource("image" + i + ".gif"));
int j = 5;
while( j >= 0 ){
Icon image = images[j];
buttons[j] = new JButton(image);
buttons[j].setPreferredSize(dim);
panel.add(buttons[j]);
j--;
}
add(panel, BorderLayout.SOUTH);
j = 3;
while( j>=0){
Icon image = new ImageIcon(getClass().getResource("image6.gif"));
labels[j] = new JLabel(image);
labels[j].setPreferredSize(dim);
if (j==3){
labels[j].setBounds(200,135,75,100);
}
else if (j==2){
labels[j].setBounds(313,70,75,100);
}
else if (j==1){
labels[j].setBounds(425,135,75,100);
}
else if (j==0){
labels[j].setBounds(313,200,75,100);
}
add(labels[j]);
j--;
}
// add(new JLabel());
}
public static void main(String[] args) {
X frame = new X();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(700,500);
frame.setVisible(true);
}
}
1) You should read Javadocs for JPanel/JButton/JLabel and their default behaviours.
2) You should make sure that the code which you post compiles
3) You should make sure that the code AS you post it illustrates your problem
As it is your post does not meet requirements 2) and 3) and you probably did not read enough of 1)

Creating a closeable tab in Mono/GTK

I'm trying to create new GTK Notebook tabs that contain both a name (as a Label) and a close button (as a Button with an Image) with the following code:
Label headerLabel = new Label();
headerLabel.Text = "Header";
HBox headerBox = new HBox();
Button closeBtn = new Button();
Image closeImg = new Image(Stock.Close, IconSize.Menu);
closeBtn.Image = closeImg;
closeBtn.Relief = ReliefStyle.None;
headerBox.Add(headerLabel);
headerBox.Add(closeBtn);
headerBox.ShowAll();
MyNotebook.AppendPage(childWidget, headerBox);
This seems to work just fine; however, the button is about 1.5 - 2 times the size is needs to be, so there is a lot of extra space around the image inside the button. Having looked at remove inner border on gtk.Button I now see that the culprit is the "inner-border" style property of the GtkButton, but (being new to GTK) I can't seem to figure out how to override its value.
Is there some method of doing this that I'm missing? I don't have any reservations about not using a Button/Image combination, so any more obvious suggestions are welcome.
Note: I have seen the suggestion in the linked question to use an EventBox, but I was not able to add the Relief and mouseover effects to that Widget.
You are in luck. I just made the exact same thing yesterday, and can fortunately give you some code. The trick is to create a Custom Tab Widget.
public class MultiTab : Gtk.Box
{
public Gtk.Label Caption;
Gtk.Image img = new Gtk.Image(Platform.IMG + "tab_close.ico");
public Gtk.ToolButton Close;
public Gtk.Notebook _parent;
public MultiTab ( string name )
{
CreateUI(name);
}
public MultiTab(string name, Gtk.Notebook parent)
{
_parent = parent;
CreateUI(name);
CreateHandlers();
}
void CreateUI(string name)
{
Caption = new Gtk.Label(name);
Close = new Gtk.ToolButton(img,"");
PackStart( Caption );
PackStart( Close );
ShowAll();
Close.Hide();
}
void CreateHandlers()
{
Close.Clicked += delegate {
_parent.RemovePage(_parent.CurrentPage);
};
}
public bool Active;
}
Next all you have to do is use this widget(or a similar one created by you) in Gtk.Notebook like this:
MyNoteBook.AppendPage(new <YourPage>(), new MultiTab("<your caption>",this));
And You're done.
Here is a screenshot:
Add this:
RcStyle rcStyle = new RcStyle ();
rcStyle.Xthickness = 0;
rcStyle.Ythickness = 0;
closeBtn.ModifyStyle (rcStyle);
Add items to box using Gtk.Box.PackStart/PackEnd methods rather than generic Gtk.Container.Add method. PackStart/PackEnd will allow you control how child widgets will be allocated space:
headerBox.PackStart (headerLabel, true, true, 0);
headerBox.PackEnd (closeBtn, false, false, 0);