i have a two frame, frameA and frameB, in frameA i add one button with name buttonA to show frameB and progressbar (setIndeterminate(false)), in frameB i add one button with name buttonB , i want to when i click buttonB, progressbar in frameA.setindeterminate(true)
in frameA
frameB b;
public frameA() {
initComponents();
progressbar.setIndeterminate(false);
b = new frameB();
}
public JProgressBar getProgressbar() {
return progressbar;
}
private void buttonAActionPerformed(java.awt.event.ActionEvent evt)
{
b.setVisible(true);
}
in frameB
i use this code in event buttonB clicked
private void buttonBActionPerformed(java.awt.event.ActionEvent evt) {
frameA a= new frameA();
a.getProgressbar().setIndeterminate(true);
}
but it doesnt worked
This...
private void buttonBActionPerformed(java.awt.event.ActionEvent evt) {
frameA a= new frameA();
a.getProgressbar().setIndeterminate(true);
}
Isn't going to work, you've just created another instance of frameA that's not visible. It has no relationship to the frame that is currently open.
There are any number of ways you could achieve this...
You could...
Pass a reference of frameA to frameB as part of the constructor call for frameB. Then in you actionPerformed method, you would simply use this reference to change the progress bar state.
But this would create a tight coupling between frameA and frameB which would greatly reduce the re-use of frameB
You could...
Provide a means by which an interested party could attach an ActionListener to frameB which would be triggered when the button is clicked.
This assumes a work flow and exposes components to outside sources (via the ActionEvent#getSource), which could allow people to change your component...
You probably should...
Fire a PropertyChanged event.
This is probably the easiest and safest of all the options I've come up with. Using a property change listener in this manner means you don't need to expose the JProgressBar, the JButton or produce a tight link between the two frames.
Property change support is built in to Container so all components/controls have it.
For example, you would attach a PropertyChangeListener to b when you construct it.
b = new frameB();
b.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals("progressState")) {
progressbar.setIndeterminate((Boolean)evt.getNewValue());
}
}
});
Add in bFrame's actionPerformed method, you would simple call...
firePropertyChange("progressState", false, true);
When you want to set the indeterminate state (you could swap the boolean values to reset it if you wanted to)
Related
I have an array of Tile objects (Panel, Button to a tile) in a JPanel, 20x20. If button 1 is clicked, a thing happens, button 2 is pressed, a thing happens, etc.
I want a specific function to happen every time a button other than one in the top row is clicked (the top row of buttons all have functions assigned, the other 380 buttons do not have assigned functions).
So in the top buttons' cases I have the code:
if(e.getSource() == tiles[0][0].button)
{
//do stuff
}
else if(e.getSource() == tiles[0][1].button)
{
//do stuff
}
For the other buttons, I want something along the lines of:
JButton button;
button = e.getSource();
JPanel hostPanel = button.PanelInWhichButtonisContained();
but I'm not sure what the syntax or what sort I would to do achieve that task. I don't really have any code to present prior attempts because I'm not sure how to approach this task, but I haven't been able to find anything on the World Wide Web to help me in this task.
I'm currently just using default application window libraries and classes (javax.swing, java.awt, etc) but I'm completely open to downloading external libraries.
Determining the "source" of an action like a button press in the actionPerformed method is usually brittle (and fortunately, hardly ever necessary).
This means that this is highly questionable:
class ButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
// DON'T DO THIS!
if (e.getSource() == someButton) doThis();
if (e.getSource() == someOtherButton) doThad();
}
}
You should usually NOT do this.
And of course, it's even worse to add casts and walk up some container hierarchy:
// DON'T DO THIS!
Object source = e.getSource();
Component button = (Component)source;
Component parent = button.getParent();
if (parent == somePanel) doThis();
if (parent == someOtherPanel) doThat();
In basically all cases, it is far more flexible and elegant to attach a listener to the button that is specific for the button - meaning that it knows what the button should do.
For individual buttons, this can be solved the old-fashioned way, using an anonymous inner class:
class Gui {
void create() {
JButton startButton = new JButton("Start");
startButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
startSomething();
}
});
}
private void startSomething() { ... }
}
The same can be written far more concisely using lambda expressions with Java 8:
class Gui {
void create() {
JButton startButton = new JButton("Start");
startButton.addActionListener(e -> startSomething());
}
private void startSomething() { ... }
}
(A side note: I consider it as a good practice to only call a single method in the ActionListener implementation anyhow. The actionPerformed method should not contain many lines of code, and particularly no "business logic". There should be a dedicated method for what the button does - for example, to startSomething, as in the example above)
For buttons that are contained in arrays, as in the example in your question, there is a neat trick to retain the information about the button that was clicked:
class Gui {
JButton buttons[];
void create() {
buttons = new JButton[5];
for (int i=0; j<buttons.length; i++) {
int index = i;
buttons[i] = new JButton("Button " + i);
buttons[i].addActionListener(e -> clickedButton(index));
}
}
private void clickedButton(int index) {
System.out.println("Clicked button at index " + index);
}
}
In many cases, you then don't even have to keep the JButton buttons[] array any more. Often you can just create the buttons, add them to some panel, and then are only interested in the index that is passed to the clickedButton method. (The button[] array may be necessary in some cases, though - for example, if you want to change the label of a button after it was clicked).
Background Information: I am currently working in a Dialog class I have extended for my game. Inside of this dialog's content table I have both an Image and a Table (lets call it ioTable). Inside of ioTable I have a combination of both Labels and TextFields. The idea is that the dialog becomes a sort of form for the use to fill out.
Next, inside of the Dialog's button table, I want to include a "Clear" TextButton (clearButton). The idea that clearButton will clear any values written to the TextFields of ioTable.
My Question: Is is possible to add a listener to each of the TextFields of ioTable that will trigger when clearButton is pressed. As always, any other creative solution is more than welcome.
You could just give the EventListener a reference to the table you want to clear:
// Assuming getSkin() and ioTable are defined elsewhere and ioTable is final
TextButton clearButton = new TextButton("Clear", getSkin());
clearButton.addListener(new EventListener() {
#Override
public boolean handle(Event event) {
for(Actor potentialField : table.getChildren()) {
if(potentialField instanceof TextField) {
((TextField)potentialField).setText("");
}
}
return true;
}
});
// Add clearButton to your dialog
If you see yourself creating multiple clearButtons, you could easily wrap this in a helper method or extend TextButton.
I have several actionListeners throughout my code for when I push a button, it changes tabs between the ones I have.
However, I would like to create a general action that depending on which button was pressed (through an int), it changed to a different tab. This is the current actionListener I have.
JButton btnSaveAddESS = new JButton("Save");
btnSaveAddESS.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
tabbedBackground.setSelectedIndex(0);
tabbedBackground.setEnabledAt(1, false);
}
});
With this, I would like to create a general action, however , while creating the action as a different class, I am not able to access the TabbedPane (tabbedBackground) component.
How can I implement this, avoiding actionListeners?
Thanks,
Nhekas
changeTab(int i){
tabbedBackground.setSelectedIndex(i);
tabbedBackground.setEnabledAt(i, false);
}
public void actionPerformed(ActionEvent e) {
int i = Integer.parseInt(Jbutton.getText());
changeTab(int i);
}
what you need is actually a method which handles the operation pass an int to the method changetab and the method will change the selectedTab
I am make a project on cars. How can I make distributor frame popup and cars frame not visible and close automatic? Kindly send any solution in simple and effective way.
I have done coding this way:-
{
Cars frm1=new Cars();
Distributor frm2=new Distributor();
frm2.setVisible(true);
frm1.setVisible(false);
frm1.setDefaultCloseOperation(frm1.DISPOSE_ON_CLOSE);
}
".Please help me to how I can make distributor frame popup and cars frame is not visible and close automatic."
Ok so in Netbeans GUI Builder, you may want to do the following (this is assuming you have created two separate JFrame form files
In the frame that is the launching program (we'll call it MyFrame1) add a button to it (we'll call it jButton1)
Add a listener to the button, then the following code should be auto-generated
public void jButton1ActionPerforemd(javax.swing.ActionEvent evt) {
}
In that actionPerformed, just instantiate the second frame (we'll call it MyFrame2) and setVisible(false) to MyFrame1. MyFrame2 should already be visible upon instantiation, so you wouldn't have to setVisisble(true) on it
public void jButton1ActionPerforemd(javax.swing.ActionEvent evt) {
MyFrame2 frame2 = new MyFrame2();
MyFrame1.this.setVisible(false);
// You can also use MyFrame1.this.dispose(); dependind if you ever need to use that frame again
}
I think this should work
you need to setVisible Jframe2 as true...so it can apear on output sceen
public void jButton1ActionPerforemd(javax.swing.ActionEvent evt)
{
myFrame2 frame2=new myframe2();
myframe1.this.setVisible(false);
frame2.setVisible(true);
}
create action event for the button such that when when you click will take
you
to the next page for my case next page is nextjFrame
private void nextButtonActionPerformed(java.awt.event.ActionEvent evt) {
setVisible(false);
nextjFrame ob=new nextjFrame();
ob.setVisible(true);
}
private void BTNConvertActionPerformed(java.awt.event.ActionEvent evt) {
/*
This is the action performed event for my Button "BTNConvert"
*/
java.awt.EventQueue.invokeLater
(new Runnable()
{
public void run()
{
new JFrame2().setVisible(true);
}
});
/*
This will set the second Frame Visible.
*/
JFrame1.this.setVisible(false);
/*
This should set the first frame invisible or whatever. Any other code should be
written before the curly brace below.
*/
}
//You're Welcome.
This has been bugging me for a while. If I define setText on a JButton before defining setAction, the text disappears:
JButton test = new JButton();
test.setText("test"); // Before - disappears!
test.setAction(new AbstractAction() {
public void actionPerformed(ActionEvent e) {
// do something
}
});
this.add(test);
If it's after, no problems.
JButton test = new JButton();
test.setAction(new AbstractAction() {
public void actionPerformed(ActionEvent e) {
// do something
}
});
test.setText("test"); // After - no problem!
this.add(test);
Furthermore, if I set the text in the JButton constructor, it's fine! Yarghh!
Why does this happen?
As described in the documentation:
Setting the Action results in immediately changing all the properties
described in Swing Components Supporting Action.
Those properties are described here, and include text.
Have a look at
private void setTextFromAction(Action a, boolean propertyChange)
in AbstractButton. You can see it's calling setText() based on the action.
It looks like you can call setHideActionText(true); to sort out your problem.
This is because Action has name for the control as well. Since you are not setting any name in the Action it is getting set to empty string.
1) Listeners put all Events to the EDT,
2) all events are waiting in EDT and output to the screen would be done in one moment
3) you have to split that to the two separate Action inside Listener
setText()
invoke javax.swing.Timer with Action that provide rest of events inside your original ActionListener
If you only want to handle the event, you don't need Action. You can add an ActionListener:
JButton test = new JButton();
test.setText("test");
test.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// do something
}
});
this.add(test);
Calling setAction overrides pre-set text.