I am coding a little Plugin for Eclipse (using SWT), which creates a view with a couple of buttons. In order not to produce redundant code I want to create some kind of factory method to create my buttons for me. The call would be something like:
Button button0 = createButton(new Button(parent, SWT.PUSH), "Test DB zurücksetzen", btnHight, btnWidth, new FormAttachment(0, 2), new FormAttachment(0,2));
My factory, so far, looks like this:
private Button createButton(Button buttonToCreate, String buttonText, int height, int width, FormAttachment left, FormAttachment top) {
buttonToCreate.setText(buttonText);
FormData formData = new FormData();
formData.height = height;
formData.width = width;
formData.left = left;
formData.top = top;
buttonToCreate.setLayoutData(formData);
buttonToCreate.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
Actions.editPropertys();
}
});
return buttonToCreate;
}
My Question is: How can I pass the Method of the Actions class I want to execute to the factory as a parameter?
You could convey it as a Runnable parameter of the method.
For example :
private Button createButton(Button buttonToCreate, String buttonText, int height, int width, FormAttachment left, FormAttachment top, Runnable actionOnSelection) {
// ...
buttonToCreate.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
actionOnSelection.run(); // change here
}
});
}
and invoke it :
Button button0 = createButton(new Button(parent, SWT.PUSH), "Test DB zurücksetzen", btnHight, btnWidth, new FormAttachment(0, 2), new FormAttachment(0,2),
Actions::editPropertys); // other change here
Related
hi i am newbie to blackberry.i will be having two buttons one for addition of rows and other for deletion of rows.
|--------------------------------------------|
||----------------------------------||------||
||labelfield ||Bitmap||
||__________________________________||______||
|____________________________________________|
|--------------------------------------------|
| Editfield |
|--------------------------------------------|
Above is customized view of datepicker,Where on click of bitmap datepicker popups to choose date and that date value get binded to edit field,this is contained in one row and other row contains an edit field which allows to enter amount which shall be formatted as user enter's numerals.
Initially two default row will be present to choose date and enter amount.On click of add button these two rows shall be added.and these rows values will be retrieved whenever required.
similarly on click of deletion button these two rows will get deleted.If user has to add next two rows the previous rows must be filled.
the code i have used for datepicker is given below
VerticalFieldManager datevertfield = new VerticalFieldManager();
String pattern = "MM/dd/yyyy";
String dateInString = new SimpleDateFormat(pattern).format(new Date());
LabelField lblcal1 = new LabelField("Date", DrawStyle.LEFT
| Field.FIELD_LEFT) {
public void paint(Graphics g) {
g.setColor(0xffffff);
super.paint(g);
}
};
datevertfield.add(lblcal1);
HorizontalFieldManager datepickerHoriztalField = new HorizontalFieldManager();
HorizontalFieldManager dateHoriztalField = new HorizontalFieldManager()
{
protected void sublayout(int maxWidth, int maxHeight) {
super.sublayout(Display.getWidth() - horiwidth, horiheight);
setExtent(Display.getWidth() - horiwidth, horiheight);
}
};
XYEdges xyEdge1 = new XYEdges(border, border, border, border);
XYEdges xyEdgeColors1 = new XYEdges(0x2AACFF, 0x2AACFF, 0x2AACFF,
0x2AACFF);
Border aBorder1 = BorderFactory.createSimpleBorder(xyEdge1,
xyEdgeColors1, Border.STYLE_SOLID);
dateHoriztalField.setBorder(aBorder1);
datepickerHoriztalField.add(dateHoriztalField);
BitmapField iconimg = new BitmapField(
GPATools.ResizeTransparentBitmap(
Bitmap.getBitmapResource("Calender.png"),
imgwidth, imgheight, Bitmap.FILTER_LANCZOS,
Bitmap.SCALE_TO_FIT), Field.FOCUSABLE) {
protected boolean navigationClick(int status, int time) {
try {
DateTimePicker datePicker = DateTimePicker.createInstance();
datePicker.doModal();
Calendar cal = datePicker.getDateTime();
datePicker.setMaximumDate(cal.getInstance());
Date curtime = cal.getTime();
DateFormat formattertime = new SimpleDateFormat(
"MM/dd/yyyy");
String currentTime = formattertime.format(curtime);
txtpickdate.setText(currentTime);
} catch (Exception e) {
}
return true;
}
};
txtpickdate = new LabelField("Enter Date", DrawStyle.LEFT
| Field.FIELD_LEFT) {
protected void paint(Graphics g) {
g.setColor(Color.WHITE);
super.paint(g);
}
};
dateHoriztalField.add(txtpickdate);
datepickerHoriztalField.add(iconimg);
datevertfield.add(datepickerHoriztalField);
add(datevertfield);
This is code used for date picker row like this i want to add datepiker row and next edit field row on click of butn .and this could be deleted on click of delete btn.
In this i need to know how to add and delete these rows and how to know whether user has entered previous Date and edit field row to do validation.
Could anyone give me idea on how to start with this.Code example will be appreciated.
I'm not sure if I understood the question or not, but from what I understand you are looking for:
A label & Button to select date
EditField restricted to numerical text
Button to create a field from a date and number
Created Fields can be deleted
I created a smallish example for doing this. I did not include the number restriction on the text field, but the rest should be a decent base to start from. I would recommend not using a BitmapField as a button because it won't be good for ux. You'll likely want a field with images for each state (none, focused, pressed)
public final class MyScreen extends MainScreen
{
private Calendar calendar;
private LabelField labelField;
private BitmapField bitmapField;
private EditField editField;
private SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
public MyScreen()
{
super(NO_HORIZONTAL_SCROLL);
// ----- TODO ------
// Too lazy to include a bmp, so I generated one. You should replace this with your icon
Bitmap bmp = new Bitmap(50, 50);
Graphics g = Graphics.create(bmp);
g.setColor(0xEFEFEF);
g.fillRect(0, 0, bmp.getWidth(), bmp.getHeight());
// ------------------
bitmapField = new BitmapField(bmp, FOCUSABLE)
{
protected boolean navigationClick(int status, int time)
{
if (calendar == null)
{
calendar = Calendar.getInstance();
}
DateTimePicker datePicker = DateTimePicker.createInstance(calendar);
datePicker.doModal();
calendar = datePicker.getDateTime();
if (calendar == null)
{
labelField.setText("null"); // Your error message here
}
else
{
labelField.setText(formatter.format(calendar.getTime()));
}
return true;
}
};
labelField = new LabelField(null, USE_ALL_WIDTH) // Tell labelField to use as much width as possible
{
protected void layout(int width, int height)
{
// Layout the label as though less space is available (to fit the bitmap button in)
super.layout(width - bitmapField.getBitmapWidth(), height);
}
};
HorizontalFieldManager manager = new HorizontalFieldManager(USE_ALL_WIDTH);
add(manager);
manager.add(labelField);
manager.add(bitmapField);
editField = new EditField(USE_ALL_WIDTH);
add(editField);
ButtonField addButton = new ButtonField("ADD")
{
protected boolean navigationClick(int status, int time)
{
String text = editField.getText();
if ((calendar != null) && (text != null) && (text.length() > 0))
{
add(new EntryField(calendar.getTime(), text));
}
else
{
// TODO notify invalid data?
}
return true;
}
};
add(addButton);
}
public class EntryField extends HorizontalFieldManager
{
public EntryField(Date date, String text)
{
super(USE_ALL_WIDTH);
// ----- TODO ------
// Too lazy to include a bmp, so I generated one. You should replace this with your icon
Bitmap bmp = new Bitmap(50, 50);
Graphics g = Graphics.create(bmp);
g.setColor(0xFF0000);
g.fillRect(0, 0, bmp.getWidth(), bmp.getHeight());
// ------------------
final BitmapField bitmapField = new BitmapField(bmp, FOCUSABLE)
{
protected boolean navigationClick(int status, int time)
{
EntryField.this.getManager().delete(EntryField.this); // Remove this field from its parent
// Depending on what kind of interactions this field exposes, this will most likely need to make use of a callback instead.
return true;
}
};
final LabelField labelField = new LabelField(formatter.format(date) + " - " + text, USE_ALL_WIDTH) // Tell labelField to use as much width as possible
{
protected void layout(int width, int height)
{
// Layout the label as though less space is available (to fit the bitmap button in)
super.layout(width - bitmapField.getBitmapWidth(), height);
}
};
add(labelField);
add(bitmapField);
}
}
}
I'm am trying to properly setup button clicks for my UI. I want my buttons to respond right after clicking them instead of releasing by using ClickListeners touchDown method.
I've created a class which creates and displays a table with text input:
public class InputBox {
public static float OFFSET = 20;
private Table table;
private TextField inputField;
private TextButton okButton;
private TextButton closeButton;
private String saveText;
private TextButtonStyle style;
private Skin skin;
public InputBox(Skin skin, float x, float y, float width, float height, boolean visible) {
this.skin = skin;
table = new Table();
// Creating a new style as suggested.
style = new TextButtonStyle();
style.up = skin.getDrawable("button_normal_up");
style.down = skin.getDrawable("button_normal_down");
style.font = skin.getFont("default");
inputField = new TextField("", skin);
okButton = new TextButton("Ok", style);
okButton.addListener(new ClickListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
if (button != Buttons.LEFT) {
return false;
}
Game.resources.getSound("click_2").play();
table.setVisible(false);
if (inputField.getText().equals("")) {
saveText = null;
return false;
}
saveText = inputField.getText();
return true;
}
});
closeButton = new TextButton("Close", style);
closeButton.addListener(new ClickListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
if (button != Buttons.LEFT) {
return false;
}
Game.resources.getSound("click_2").play();
saveText = null;
table.setVisible(false);
return true;
}
});
table.setVisible(visible);
table.setX(x);
table.setY(y);
table.setWidth(width);
table.setHeight(height);
table.add(inputField).colspan(2).center().width(width - OFFSET).expand().padRight(2);
table.row();
table.add(okButton).width(width / 2 - OFFSET / 2).right();
table.add(closeButton).width(width / 2 - OFFSET / 2).left();
table.pad(5);
}
public void setUnclicked() {
style.down = skin.getDrawable("button_normal_up");
// I think these two lines ar uneeded.
okButton.setStyle(style);
closeButton.setStyle(style);
}
public void setClicked() {
style.down = skin.getDrawable("button_normal_down");
// Same here.
okButton.setStyle(style);
closeButton.setStyle(style);
}
public void setText(String text) {
inputField.setText(text);
}
public String getSaveTextOnce() {
String temp = saveText;
saveText = null;
return temp;
}
public void setBackground(Drawable background) {
table.setBackground(background);
}
public boolean isVisible() {
return table.isVisible();
}
public void setVisible(boolean visible) {
table.setVisible(visible);
}
public Table getTable() {
return table;
}
}
The table is being set to visible after clicking a different button:
// Save map button.
saveMap = new ImageButton(new ImageButtonStyle());
saveMap.getStyle().imageUp = uiSkin.getDrawable("save");
saveMap.getStyle().up = uiSkin.getDrawable("button_flat_up");
saveMap.getStyle().down = uiSkin.getDrawable("button_flat_down");
saveMap.addListener(new ClickListener() {
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
if (button != Buttons.LEFT) {
return false;
}
Game.resources.getSound("click_2").play();
if (saveBox.isVisible()) {
saveBox.setVisible(false);
saveBox.setUnclicked();
return false;
}
saveBox.setVisible(true);
saveBox.setClicked();
return true;
}
});
The entire class for the saveMap button: http://pastebin.com/62ZGfcch
However, if I close the table by clicking the "ok" or "close" button and click and hold the mouse over the show table button, the table reappears with last clicked button being held down.
This video illustrates whats happening:
https://www.youtube.com/watch?v=Jf3WzU8G4dE&feature=youtu.be
If I move the mouse while holding it down, the last clicked button on the table resets to its normal state.
First i would recommend you to rather use a TextButtonStyle instance for setting the style of the buttons rather than a Skin instance.
You could somehow get the TextButton's references to the saveMap.addListener anonymous inner class. Then you could manualy set the style of the Ok and Cancel TextButton's, something like this:
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
Game.resources.getSound("click_2").play();
if (saveBox.isVisible()) {
saveBox.setVisible(false);
okButtonReference.setStyle(unclickedTextButtonStyle) // Not-clicked TextButtonStyle as parameter
cancelButtonReference.setStyle(unclickedTextButtonStyle) // Not clicked TextButtonStyle as parameter.
return false;
}
saveBox.setVisible(true);
return true;
}
By forcing the TextButton to change it's TextButtonStyle by calling setStyle() you can be confident that the button will change.
Also i noticed that you are not calling the debug() method on the Table object. This is not necessary but it is advisable:
table.add(inputField).colspan(2).center().width(width - OFFSET).expand().padRight(2);
table.row();
table.add(okButton).width(width / 2 - OFFSET / 2).right();
table.add(closeButton).width(width / 2 - OFFSET / 2).left();
table.pad(5);
table.debug();
After more fiddling I found out that the way I setup my games InputProcessor was causing this issue. I did not handle the touchUp event properly.
Game.inputs.addProcessor(new InputProcessor() {
...
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
releasedButton = -1;
if (UI.isOver()) {
return false;
}
if (button == Buttons.LEFT) {
releasedButton = Buttons.LEFT;
}
if (button == Buttons.RIGHT) {
releasedButton = Buttons.RIGHT;
}
return true; // <--- setting this to false fixes the issue
}
});
I have a Navigator class and a custom DialogBox class which is descended from GridPane.
public DialogBox(final JDialog jdialog) {
Label lblKeyName = new Label("Enter New Key");
Label lblKeyType = new Label("Select Key Type");
TextField txtKeyName = new TextField();
ComboBox cboKeyType = new ComboBox();
txtKeyName.getText();
Button btnOk = new Button("OK");
Button btnCancel = new Button("Cancel");
btnOk.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
//TODO: Somehow return the values in the ComboBox and TextField
}
});
btnCancel.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
jdialog.setVisible(false);
}
});
txtKeyName.prefWidth(300);
cboKeyType.prefWidth(300);
this.add(lblKeyName, 0, 0);
this.add(lblKeyType, 0, 1);
this.add(txtKeyName, 1, 0);
this.add(cboKeyType, 1, 1);
this.add(btnOk, 0, 2);
this.add(btnCancel, 1, 2);
}
This is the constructor for my DialogBox.
JFXPanel fxPanel = new JFXPanel();
testBox = new DialogBox(jdialog);
fxPanel.setScene(new Scene(testBox));
jdialog.add(fxPanel);
jdialog.setVisible(true);
How can I retrieve the values in the TextField and ComboBox? I can slightly recall a long ago class where the professor mentioned a technique involving the calling class (Navigator in this case) implementing an Interface and then passing itself to the DialogBox class to retrieve values. Unfortunately I have not found anything and cannot remember how it is done.
Assuming that the dialog is modal, basically, once btnOk or btnCancel button is pressed you need to change some kind of state flag which you can interrogate to determine how the dialog was closed...
// This will also handle the use case where the user presses the "x" button...
private boolean wasCancelled = true;
//...
public boolean wasCancelled() {
return wasCancelled;
}
In you action listeners, you need to set the state appropriately.
btnOk.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
wasCancelled = false;
jdialog.setVisible(false);
}
});
btnCancel.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
wasCancelled = true;
jdialog.setVisible(false);
}
});
Now, once the dialog returns, you need to check this flag...
jdialog.add(fxPanel);
jdialog.setVisible(true);
if (!jdialog.wasCancelled()) {
//...
}
You then need to supply "getter" methods to allow a caller to extract the values from the dialog...
public String getKey() {
return txtKeyName.getText();
}
public String getType() {
return cboKeyType.getSelectionModel().getValue();
}
This will mean you will need to create these two fields as instance variables
I want to use the JFace PopupDialog as lightweight dialog for user input. But I have some problems with the background color of text widgets.
As you can see below in 1, a SWT.MULTI text widget has no background and border, a SWT.SINGLE text widget has no background.
I tried to override the background color with:
Text comment = new Text(composite, SWT.MULTI|SWT.BORDER);
comment.setFocus();
comment.setBackground(new Color(Display.getDefault(), new RGB(000, 000, 000)));
// method of PopupDialog
applyBackgroundColor(new Color(Display.getDefault(), new RGB(000, 000, 000)), comment);
Does anybody has any idea how to handle this properly?
Thanks in advance!
EDIT: As requested, here is the source for the popup. I subclassed the PopupDialog, as I wanted the popup to be opened next to the Cursor location:
public class MouseLocationPopupDialog extends PopupDialog {
private final static int SHELL_STYLE = PopupDialog.INFOPOPUP_SHELLSTYLE;
public MouseLocationPopupDialog(Shell parent, String infoText) {
this(parent, SHELL_STYLE, true, false, false, false, false, null, infoText);
}
public MouseLocationPopupDialog(Shell parent, String titleText, String infoText) {
this(parent, SHELL_STYLE, true, false, false, false, false, titleText, infoText);
}
public MouseLocationPopupDialog(Shell parent, String infoText, final Point size) {
this(parent, infoText);
getShell().setSize(size);
}
public MouseLocationPopupDialog(Shell parent, int shellStyle, boolean takeFocusOnOpen, boolean persistSize, boolean persistLocation, boolean showDialogMenu, boolean showPersistActions, String titleText, String infoText) {
super(parent, shellStyle, takeFocusOnOpen, persistSize, persistLocation, showDialogMenu, showPersistActions, titleText, infoText);
}
#Override
protected void adjustBounds() {
super.adjustBounds();
Display d = Display.getCurrent();
if (d == null) {
d = Display.getDefault();
}
Point point = d.getCursorLocation();
getShell().setLocation(point.x + 9, point.y + 14);
}
}
The actual usage is as follows:
final PopupDialog dialog = new MouseLocationPopupDialog(HandlerUtil.getActiveShell(event), "Title", "Bottom bar") {
#Override
protected Control createDialogArea(Composite parent) {
Control composite = super.createDialogArea(parent);
Composite table = new Composite((Composite) composite, SWT.NONE);
table.setLayout(new GridLayout(2, true));
// text is a member variable
text = new Text(table, SWT.SINGLE | SWT.BORDER);
Button submit = new Button(table, SWT.PUSH);
return composite;
}
#Override
protected Control createContents(Composite parent) {
Control contents = super.createContents(parent);
final Color backgroundColor = new Color(Display.getCurrent(), new RGB(255, 255, 255));
text.setBackground(backgroundColor);
final Color foregroundColor = new Color(Display.getCurrent(), new RGB(0,0,0));
text.setForeground(foregroundColor);
backgroundColor.dispose();
foregroundColor.dispose();
return contents;
}
};
dialog.open();
Note that this Popup is independent from other UI elements: The code will not wait for the completion of the popups open() like other JFace dialogs (e.g. TitleAreaDialog)
First of all, use SWT.BORDER instead of SWT.BORDER_SOLID. If you're lucky, this somehow causes your problem. Other than that, from your small snippet alone it's hard to see what goes wrong. Unless there is some other code that resets the background color later on, this should work.
Update:
Try to override the method getBackground() of PopupDialog and let it return the color you want. Your code probably is in createDialogArea(..) and PopupDialog applies this color to basically everything after your code.
If you only want to change the background color of specific controls, you could try the following:
#Override
protected Control createContents(Composite parent) {
Composite contents = super.createContents(parent);
// set the color here
return contents;
}
I've been banging away at this for a while now and I can't seem to get anywhere. I've tried all of the examples I can find online and nothing seems to work! I haven't been able to find much on this problem which leads me to think I'm missing something basic. . .
In my Eclipse RCP program I want to display a dialog that will show a list of errors that occurred while loading a data file. I have overridden TitleAreaDialog and simply want to display a scrollable Text containing the list of errors and an OK button.
The problem is that the Text vertical scroll bars don't become active - the Text just grows taller to fit the text. This makes the dialog window height increases until it either fits the Text box or until it reaches the height of the screen - and then it just cuts off the bottom of the Text box.
How do I prevent the Dialog/Text box from growing too large? What am I missing?
Thanks for your help!!
-Christine
...
Here is a simple program showing my Dialog:
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.swt.*;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
public class ScrollableDialogRunner {
public static void main(String[] args) {
System.out.println("starting");
Display display = new Display ();
Shell shell = new Shell (display);
String errors = "one\ntwo\nthree\nfour\nfive\n";
for(int i = 0; i < 5; i++){
errors += errors;
}
ScrollableDialog dialog = new ScrollableDialog(shell, "Errors occurred during load", "The following errors occurred while loaded file 'x.data'", errors);
dialog.open();
}
}
class ScrollableDialog extends TitleAreaDialog {
private String title;
private String text;
private String scrollableText;
public ScrollableDialog(Shell parentShell, String title, String text, String scrollableText) {
super(parentShell);
this.title = title;
this.text = text;
this.scrollableText = scrollableText;
}
#Override
protected Control createDialogArea(Composite parent) {
GridLayout layout = new GridLayout();
layout.numColumns = 1;
parent.setLayout(layout);
GridData gridData = new GridData();
gridData.grabExcessHorizontalSpace = true;
gridData.horizontalAlignment = GridData.FILL;
Text scrollable = new Text(parent, SWT.BORDER | SWT.V_SCROLL);
scrollable.setLayoutData(gridData);
scrollable.setText(scrollableText);
return parent;
}
#Override
public void create() {
super.create();
setTitle(title);
setMessage(text, IMessageProvider.ERROR);
}
#Override
protected void createButtonsForButtonBar(Composite parent) {
Button okButton = createButton(parent, OK, "OK", true);
okButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
close();
}
});
}
#Override
protected boolean isResizable() {
return false;
}
}
Assign a size to the dialog; otherwise, the dialog will layout the children asking them for their "preferred" size (which is infinite for the text widget) and will resize itself accordingly.
[EDIT] This version works. See my comments for details.
class ScrollableDialog extends TitleAreaDialog {
private String title;
private String text;
private String scrollableText;
public ScrollableDialog(Shell parentShell, String title, String text, String scrollableText) {
super(parentShell);
this.title = title;
this.text = text;
this.scrollableText = scrollableText;
}
#Override
protected Control createDialogArea(Composite parent) {
Composite composite = (Composite) super.createDialogArea (parent); // Let the dialog create the parent composite
GridData gridData = new GridData();
gridData.grabExcessHorizontalSpace = true;
gridData.horizontalAlignment = GridData.FILL;
gridData.grabExcessVerticalSpace = true; // Layout vertically, too!
gridData.verticalAlignment = GridData.FILL;
Text scrollable = new Text(composite, SWT.BORDER | SWT.V_SCROLL);
scrollable.setLayoutData(gridData);
scrollable.setText(scrollableText);
return composite;
}
#Override
public void create() {
super.create();
// This is not necessary; the dialog will become bigger as the text grows but at the same time,
// the user will be able to see all (or at least more) of the error message at once
//getShell ().setSize (300, 300);
setTitle(title);
setMessage(text, IMessageProvider.ERROR);
}
#Override
protected void createButtonsForButtonBar(Composite parent) {
Button okButton = createButton(parent, OK, "OK", true);
okButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
close();
}
});
}
#Override
protected boolean isResizable() {
return true; // Allow the user to change the dialog size!
}
}