Change button title issue - java

Hi I use GWT and I have a com.smartgwt.client.widgets.Button that has the following eventHandler:
Button viewCommentsButton = new Button("View ");
viewCommentsButton.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
if (!childrenVisible) {
addChildren();
getParent().setTitle("Close");
} else {
removeChildren();
getParent().setTitle("View");
}
}
});
As you can see I tried getParent().setTitle() method but with no effect. The if works fine so I guess I can't get the reference to my button object but the code compiles and getParent returns a widget so most likely my button.
However, the addChildren and removeChildren methods are working properly but my button has the initial title all the time. Any ideas why? Hope this makes sense.
Any suggestions are welcomed. Thanks.

If you are trying to set the title on viewCommentsButton, call viewCommentsButton.setTitle().
If you are trying to set the text in the button, call viewCommentsButton.setText().
For either of these you'll have to mark the button as final - declare it with final Button viewCommentsButton = ...
The context of getParent() is confusing. getParent(), the way you're using it, will return the parent of the widget in which you're defining all of this, NOT the parent of viewCommentsButton and definitely not viewCommentsButton itself.

Make your button a class variable, rather than a method variable and than you would be able to use it (refer it) inside the click handler.
For example:
viewCommentsButton = new Button("View "); //viewCommentButton is the private member.
viewCommentsButton.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
if (!childrenVisible) {
addChildren();
viewCommentButton.setTitle("Close");
viewCommentButton.setText("Close");
} else {
removeChildren();
viewCommentButton.setTitle("View");
viewCommentButton.setText("View");
}
}
});

You should use setText
setTitle is the "tooltip"

Related

Do event after click on ImageView which is inside of the tableView which contains observableArray

I have a class (TaskInOurProgram) which contains ImageView in constructer.
Here is a little code snipped - declaration and then constructer:
private ImageView closeTask;
private ImageView pauseTask;
private final Image pauseImage = new Image("file:images/pause.png");
private final Image closeImage = new Image("file:images/close.png");
public TaskInOurProgram(String name, String configName, String extensionOfTheFile) {
this.nameOfTheFile = name;
this.configName = configName;
this.extensionOfTheFile = extensionOfTheFile;
this.closeTask = new ImageView();
closeTask.setImage(closeImage);
this.pauseTask = new ImageView();
pauseTask.setImage(pauseImage);
}
Then I have a observableArrayList which contains many of these TaskInOurProgram objects.
private ObservableList<TaskInOurProgram> tasksInTheTableView = FXCollections.observableArrayList();
I have a tableView which displays this list of objects. So then it looks like this.
Object are not there from the beginning, they need to be added by clicking at button ADD TASK and because it is observableList, it will show this "tasks" immediately after adding.
WHAT I NEED: What I need is to create method inside of the controller which will do something after click on "pause" ImageView. I really do not know how to do it, I was thinking about listeners somehow. And before that I need to put click event on imageView.
Can you guys, please, help me with this? Thanks for any idea.
Try using a Button with a Graphic instead of a plain ImageView. That way you can use the Button.setOnAction() method.
Where you are currently defining your ImageView, change it to the following:
this.pauseTask = new Button("", new ImageView(pauseImage));
this.pauseTask.setOnAction(new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent event) {
pause();
}
});
You can define a method somewhere else in your program, something like this:
private void pause() {
// your code here
}
Use setOnMouseClicked() method for imageView to handle click events.
pauseTask.setOnMouseClicked(new EventHandler<Event>() {
#Override
public void handle(Event event)
{
pauseTask();
}
});
Then you can handle it in other method
void pauseTask()
{
}

Adapter pattern with Buttons, adaptor class has to know which button was pressed

This is an actionPerformed in a Swing panel with custom buttons from a framework which scrambles their classes so all methods are a():String or b():void and there is no way to make out what it actually is.
I got a compiler error becaus when I inherit this button class the compiler find a():void an a():String which is not allowed in Java. My solution was to use the adapter pattern like this:
public abstract class FactoryButton {
private CustomButton button;
public FactoryButton(int width, int height) {
button = new DynButton();
button.setSize(width, height);
}
public DynButton getButton() {
return button;
}
}
So my FactoryButton has the CustomButton class as a private member. The FactoryButton is the parent of another Button class named FactorySelectionButton
which has an action performed where I used to be able to get the source of the event:
#Override
public void actionPerformed(ActionEvent arg0) {
if (arg0.getSource() instanceof FactorySelectionButton) {
// User selected a factory
selectedItem = ((FactorySelectionButton) arg0.getSource()).getFactory();
// Close the screen, so control returns back to the parent window
cancel();
} else {
// other buttons implementation
}
}
But now since I solved one problem with the adapter pattern I have another the arg0.getSource() no longer gives me the FactorySelectionButton but it now gives a CustomButton which gives me no way to know which custom button is pressed.
The reason for not throwing away the custom button is that I am bound to the framework, I have to use it and the amount of factories can grow so I don't want hardcoded buttons.
So anyone have an idea on how I can fix this?
I found a way around it by looping over all my components and checking whether they have the button I need and they double checking whether it's really an instance of the class I want.
#Override
public void actionPerformed(ActionEvent arg0) {
for (FactoryButton component : components) {
if(component.getButton().equals(arg0.getSource()) && component instanceof FactorySelectionButton)
selectedItem = ((FactorySelectionButton) component).getFactory();
return;
}
//other buttons implementation
}

JavaFX subclassed Button - How to make Label update work?

I want to have several JavaFX Buttons that update one Label in my Application with text. For testing purposes it's just Button Text.
What I did at first worked fine and looked like this:
String Text = "...";
public void kons() {
System.out.println("Works...");
System.out.println(Text);
Tekst.setText(Text);
Button G4 = new Button("Spadantes");
G4.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
Text = G4.getText();
kons();
}
});
Then I decided to stylize my buttons with CSS and because I wanted to have several groups of buttons stylized in different way I subclassed JavaFX Button class in this way:
public class Buttons extends Button {
public Buttons(String text) {
super(text);
getStylesheets().clear();
getStylesheets().add("./Buttons.css");
Which still worked. But now I want my event handler to be moved to Button subclass (to avoid copy-pasting exactly same code into each and every button of mine). What I did looks like this:
public class Buttons extends Button {
public Buttons(String text) {
super(text);
getStylesheets().clear();
getStylesheets().add("./Buttons.css");
setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
Main.Text = getText();
Main.kons();
}
});
}
}
Main is my extend Application class
Tekst is my label.
And sadly it throws me exception about calling non-stathic method and variable from static context. From what I understand instances are static and definitions are non-static. I tried to change everything "in the way" to static but it gives me red wall of errors after clicking button (nothing in compilation process). I also tried to call instance of my Application somehow but I have no idea how (from what I understand extend Application class intantiates itself on it's own while starting program so there's no "name" by which I can call it's Label.
What I'm looking for is "quick and dirty solution" to be able to use subclassed buttons (or other sliders, text-fields, etc.) that can call a method that updates something "on screen".
[EDIT] I'm using newest Java there is of course. In case it matters.
Instead of subclassing, why not just write a utility method that creates the buttons for you? I would also not recommend making the text variable an instance variable: just reference the Label directly.
public class SomeClass {
private Label tekst ;
// ...
private Button createButton(String buttonText) {
Button button = new Button(buttonText);
button.getStylesheets().add("Buttons.css") ;
button.setOnAction(e -> tekst.setText(buttonText));
return button ;
}
}
Then, from within the same class, when you need one of those buttons you just do
Button button = createButton("Text");
If you really want to subclass (which just seems unnecessary to me), you need to pass a reference to the label to the subclass:
public class LabelUpdatingButton extends Button {
public LabelUpdatingButton(String text, Label labelToUpdate) {
super(text);
getStylesheets().add("Buttons.css");
setOnAction(e -> labelToUpdate.setText(getText()) );
}
}
Then from your class that assembles the UI you can do
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
Label tekst = new Label();
Button someButton = new LabelUpdatingButton("Button text", tekst);
// etc...
}
}
But again, creating a subclass that does nothing other than define a constructor that calls public API methods is redundant, imo.
Also, it's a bit unusual to create an entire stylesheet just for your buttons. Typically you would set a style class on the Button:
button.getStyleClass().add("my-button-class");
and then in the stylesheet you add to the Scene do
.my-button-class {
/* styles for this type of button */
}

How to create MouseClick event to detect which node is clicked? - javafx

I want to do global MouseClick event to detect which node is clicked in JavaFX. I mean when someone will click a button then event.getSource will return me reference to this button.
Any ideas, how can i do this?
One way to go about this would be to have a static variable somewhere that was of type Node, and then in the listener of the button, just assign a reference to the button in the handler to that button. ex:
public Class test {
public static Node whichClick;
myButton.setOnAction(new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent e){
whichClick = myButton;
}
});
}
And then you could access that variable from wherever.

How do I detect that a SWT dialog has been opened and is visible?

I have an SWT WizardDialog with a number of pages. When this dialog first opens I have to do a check for some conditions and if those conditions are met I need to show a popup over the freshly opened dialog.
So I have this code to listen for SWT.Show event. The event listener responds to SWT.Show to conduct its tests and show a message box:
final WizardDialog dialog = new WizardDialog(shell, wizard);
dialog.setTitle("New Wizard");
dialog.create();
dialog.getShell().addListener(SWT.Show, new Listener()
{
private boolean firstShowing = true;
#Override
public void handleEvent(Event event)
{
if (firstShowing && someConditionExists())
{
MessageBox messageBox = new MessageBox(dialog.getShell(), SWT.OK
| SWT.ICON_WARNING);
messageBox.setMessage("Test");
messageBox.open();
firstShowing = false;
}
}
});
dialog.open();
Except it's called too soon! The dialog is not visible when the handler is called. My message box appears before the dialog is visible and the dialog only appears when I dismiss the message box.
So clearly the SWT.Show is unreliable, at least on Windows where I'm running it. I've also tried putting this code into a ShellListener on the activation but that happens even before the SWT.Show example above.
So how do I reliably show a message box when the dialog is made visible?
Plan B is a dirty timer based hack where a timer is set to fire 200 ms into the future and hope that it triggers when the dialog is visible but obviously this could introduce it's own issues.
I'm using in similar situation (need that appStarted() is called after application window is visible) something like below.
public class App extends ApplicationWindow {
#Override
protected Control createContents(Composite parent) {
// ...
getShell().addShellListener(new ShellAdapter() {
#Override
public void shellActivated(ShellEvent shellevent) {
if (!started) {
Shell s = (Shell) shellevent.getSource();
s.setVisible(true);
appStarted();
started = true;
}
}
});
}
}
Maybe You can use the same like below:
final WizardDialog dialog = new WizardDialog(shell, wizard);
dialog.setTitle("New Wizard");
dialog.create();
dialog.getShell().addShellListener(new ShellAdapter() {
#Override
public void shellActivated(ShellEvent shellevent) {
if (firstShowing && someConditionExists()) {
Shell s = (Shell) shellevent.getSource();
s.setVisible(true);
MessageBox messageBox = new MessageBox(dialog.getShell(), SWT.OK | SWT.ICON_WARNING);
messageBox.setMessage("Test");
messageBox.open();
firstShowing = false;
}
}
});
dialog.open();
Instead of hooking the SWT.Show event, you may get more luck with hooking a PaintListener on to your dialog's Composite. (You'll probably want to unhook it during the first execution.)
What about overriding dialog.open() methodon your WizardDialog class? The first line of the overridden method would call super.open(), which would make it visible. Just put your custom code after that, in the .open() method.
The issue with the approach you're taking above appears to be that it responds to a Show event, which is simply notification that Show has been requested, not that the dialog is visible. The Show event could very well be designed to allow you to know when something is about to be shown, and take some action before that happens, as you've experienced.
I know that this is an old thread. But in case someone finds it useful, I found that overriding Dialog.create() rather than Dialog.open() worked for me.
it's called too soon!
I also run recently in the same trouble. The code was executed too early - my upload action (which I wanted to start automatically under some conditions) was started before the page was displayed.
This happens because the page can only be shown after the code in the SWT.SHOW listener or in the inherited setVisible() method is completed.
#Override
public void setVisible(boolean visible) {
if (visible) {
org.eclipse.ui.progress.UIJob("Auto start the upload") {
#Override
public IStatus runInUIThread(IProgressMonitor monitor) {
if (isAutoStartQcUploadSelected)
startUpload();
return Status.OK_STATUS;
}
};
uiJob.schedule();
}
super.setVisible(visible);
}
org.eclipse.ui.progress.UIJob as described FAQ_Can_I_make_a_job_run_in_the_UI_thread has solved the issue.
P.S.: Yes, I know that's an old question :-)
But it is the first one propesed by google and the hint with the UI Job was missing.
The code of marioosh can be further improved, by storing the ShellAdapter in a variable.
Remove the ShellAdapter when the listener is triggered for the first time.
The variable started is no longer needed.
The statement s.setVisible(true); is not necessary, because this event is just triggered when the shell gets visible.
public class App extends ApplicationWindow {
#Override
protected Control createContents(Composite parent) {
// ...
ShellAdapter shellActivatedAdapter = new ShellAdapter() {
#Override
public void shellActivated(ShellEvent shellevent) {
shellevent.getSource().removeShellListener(shellActivatedAdapter);
appStarted();
}
};
getShell().addShellListener(shellActivatedAdapter);
}
}

Categories

Resources