Hello my problem is: I am not able to enable a button of a form, from another class. My form class is
public class FileSending {
//Function for enabling the button
public void activate_btnSEND (boolean flag) {
SendFile.setEnabled(flag);
}
}
And the class from where i am calling this function is as follows :
public class SMS {
Public void split(){
if(check_string.equalsIgnoreCase("0001")) {
JOptionPane.showMessageDialog(null, " Recepient Has Accepted The" +
" Request.Connection Has Been Established :) ");
FileSending setBtn = new FileSending();
setBtn.activate_btnSEND(true);
}
}
}
I debugged the code to check the value that is being passed to flag and the value is "True". It also goes inside the if condition but the Button is not enabled. I don't understand what is happening here !!
Some points in your code:
First, you are enabling/disbaling, you making it visible if flag is true. You should use setEnabled(b), So SendFile.setVisible(true); will become SendFile.setEnabled(true);
Never compare boolean like this if(flag == true), it should be just if(flag)
And your methhod should be something like this:
public void changeStateOfButton (boolean flag) {
//now what ever you pass will decide whether to enable or disable the button.
myButton.setEnabled(flag);
}
Or more better you should use JToggleButton for such things.
Also improve your variable naming skills.
A small example of what I'm saying:
public class TestButtonEnable {
public static void main(String[] args) {
JFrame frame = new JFrame("TestButtonEnable");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(200, 200);
frame.setLayout(new BorderLayout());
JButton button = new JButton("Enable that button");
final MyPanel panel = new MyPanel();
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "Some message. :)");
panel.changeStateOfButton(true); // call second class method here
}
});
frame.add(button, BorderLayout.NORTH);
frame.add(panel, BorderLayout.SOUTH);
frame.setVisible(true);
}
}
And second class containing jbutton:
class MyPanel extends JPanel {
private JButton button;
public MyPanel() {
button = new JButton("Enable me");
button.setEnabled(false); // disabled by default
this.add(button);
}
public void changeStateOfButton (boolean flag) {
button.setEnabled(flag);
}
}
check if you are not creating more then one object of FileSending class ....
you must not create more then one object of that class...
check if one object is created as part of your GUI class and another is as part of SMS class..
use only one object of FileSending class
Related
I've got a problem with changing JPanels color from another class.
I'm trying to change it by clicking a button. I am creating an application where user can pick a colour theme what he wants.
First class:
public class First extends JFrame {
public JPanel contentPane = new JPanel();
public JPanel panel = new JPanel();
public First() {
JButton btnNewButton = new JButton("New button");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Second s = new Second();
s.startSecond();
}
});
}
}
Second class:
public class Second extends JFrame {
First f;
private JPanel contentPane;
public static void startSecond() {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Second sframe = new faijaso();
sframe.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public Second() {
JButton btnNewButton = new JButton("New button");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
f.panel.setBackground(Color.red);
f.panel.repaint();
f.panel.revalidate();
}
});
}
}
You have several problems with this code, but most importantly is that your First f variable is never initialized leaving it null, and so if you try to call a method off of it, the program will throw a NullPointerException. You certainly don't want to create a new First() and assign that to f since that instance will not be the same as the visualized First that already exists. Instead change the Second's constructor to accept a First argument, and then pass in the current instance when you call the Second's constructor.
public Second(First f) {
this.f = f;
// ....
and in First:
public First() {
JButton btnNewButton = new JButton("New button");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Second s = new Second();
s.startSecond(First.this); // pass in the First instance
}
});
}
Other problems --
get rid of the static code in Second as there's no need for this. Instead set the Second visible within First's ActionListener.
You really don't want to use two JFrames, and this link will tell you why: The Use of Multiple JFrames: Good or Bad Practice?.
Instead have Second be a JDialog.
I have a custom class CustomField that extends JPanel. As I often have to reuse the same pattern, my custom class is made of 2 JLabels and 2 JComboBox.
It's quite simple; the first JComboBox has ON/OFF choices and the second JComboBox is only visible if the first is set to "ON". I can manage this part.
The part that I however don't know who to design it well is that CustomField instances are in another class that is the main JFrame and in this JFrame, some parts will be visible only if the JComboBox from the CustomField class is set to "ON". I thought about using a MouseAdapter, but I don't know it is good practice.
Here is my CustomField class:
public class CustomField extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
JLabel text, portText;
JComboBox<String> testCB, option;
public CustomField(String text, String opt, String tst) {
this.text = new JLabel(text);
String[] onOffOpt= {"OFF", "ON"};
this.option = new JComboBox<String>(onOffOpt);
this.option.setSelectedItem(opt);
this.option.addItemListener(new ItemListener(){
#Override
public void itemStateChanged(ItemEvent ie) {
portText.setVisible(option.getSelectedIndex() == 1);
testCB.setVisible(option.getSelectedIndex() == 1);
}
});
this.portText = new JLabel("Test:");
String[] testChoices = {"Test", "Test2"};
this.testCB = new JComboBox<String>(testChoices);
this.testCB.setSelectedItem(tst);
this.setLayout(new FlowLayout());
add(this.text);
add(this.option);
add(this.portText);
add(this.testCB);
}
}
And here is the main JFrame:
public class Main {
CustomField cf = new CustomField("test", "ON, "Test2");
public static void main(String s[]) {
JFrame frame = new JFrame("Application");
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
panel.add(cf);
JLabel labelTest = new JLabel("Label that should be visible or not");
panel.add(labelTest);
frame.add(panel);
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Basically, I want that the labelTest visibily changes according to the CustomField settings. In the way that it is made, I can not put the labelTest in the CustomField class.
Is there a clean way to do what I want? Should I redesign the actual thing and put all the fields in the same class?
Thanks!
First, you want to expose the combobox's state with a method in CustomField:
public boolean isOn() {
return testCB.getSelectedIndex() == 1;
}
You can get an idea for how listening for state is done by looking at the method signatures in the documentation for various Swing components, which use the standard JavaBean listener pattern: You’ll want to add three public methods, and one protected method:
public void addChangeListener(ChangeListener listener) {
listenerList.add(ChangeListener.class, listener);
}
public void removeChangeListener(ChangeListener listener) {
listenerList.remove(ChangeListener.class, listener);
}
public ChangeListener[] getChangeListeners() {
return listenerList.getListeners(ChangeListener.class);
}
protected void fireChangeListeners() {
ChangeEvent event = new ChangeEvent(this);
for (ChangeListener listener : getChangeListeners()) {
listener.stateChanged(event);
}
}
(The listenerList field is inherited from JComponent.)
Now, you can simply add a call to fireChangeListeners(); whenever you detect that the user has changed the value of the On/Off combobox—that is, you’ll want to call it in your ItemListener.
As you can probably guess, your Main class can now call cf.addChangeListener, and inside that listener adjust the visibility of your label based on the value returned by cf.isOn().
You can learn a lot more by reading these.
I am writing a program which has a JFrame with a JMenu in it. Once the user clicks a menuItem, a JDialog is being called, to get a String from the user. I want to use that string in my main programm but i don't know how to return that value from the JFrame to the main programm (I managed to return the value from the JDialog to the JFrame). Any ideas?
My main::
public static void main(String[] args)
{
myFirstFrame m = new myFirstFrame();
m.setVisible(true);
String localhost = m.getLh();
System.out.println(localhost);
}
My JFrame::
public class myFirstFrame extends JFrame
{
String lh;
myDialog myD;
public myFirstFrame(JFrame mf)
{
super();
setTitle("Welcome");
setSize(300, 300);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
JMenuItem playg = new JMenuItem("Play game");
simetoxi.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent ae)
{
myD = new myDialog(myFirstFrame.this);
myD.setVisible(true);
String lh = myD.getText();
System.out.println(lh + "ASasASas");
dispose();
}
});
JMenu game = new JMenu("GAME");
game.add(playg);
JMenuBar myBar = new JMenuBar();
myBar.add(game);
setJMenuBar(myBar);
}
public String getLh()
{
return lh;
}
}
My JDialog::
public class myDialog extends JDialog
{
JTextField t1;
String sname;
public myDialog(JFrame fr)
{
super(fr, true);
setTitle("Connect");
setSize(200, 200);
setLayout(new FlowLayout());
JLabel l1 = new JLabel("Give the server name");
t1 = new JTextField(15);
add(l1);
add(t1);
JButton okb = new JButton("submit");
okb.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent ae)
{
sname = t1.getText();
dispose();
}
});
add(okb);
}
public String getText()
{
return sname;
}
}
The problem is that when main creates the Frame, it doesn't stop and wait for the value to become available before executing the rest of the main function.
There are many ways you could solve this problem. For example, rather than putting System.out.println(localhost) in main, you could put it in a different method. Then, in the Frame, call that method when you get the value.
If you really want to put that call in main, you will have to find some way to make main block until the value is available. For example, you could create a BlockingQueue, and try to dequeue the value from within main. In the Frame event handler, push the needed value onto the queue.
The main method will not wait for your JFrame to go through those steps, so calling a getter in your main program (even if you "correct"
String lh = myD.getText();
to
lh == myD.getText();
will not work. - Pass this information to a class/method that makes good use of it, perhaps processing it in a separate thread - depends of what you want to do with "localhost".
Ok, here is my problem. Class B is a class that build a GUI ,which has a textField and button. class A has an instance of class B.Now I enter some value in the textfield, when I click the button, in class A I want to print out the value I just enter in the textfield, how can I achieve that?
Code below may better explain what I want to achieve:
public class A
{
B myB = new B();
(when the JButton was clicked,
how can I get the new textfield value here?)
}
public class B
{
JLabel myLabel;
JButton myButton;
public B()
{
getContentPane().setLayout(null);
myLabel = new JLabel();
myLabel.setLocation(0,0);
myLabel.setSize(100,30);
myLabel.setBackground( new Color(-6710887) );
myLabel.setText("");
getContentPane().add(myLabel);
myButton = new JButton();
myButton.setLocation(0,50);
myButton.setSize(100,30);
myButton.setBackground( new Color(-16737895) );
myButton.setText("Submit");
getContentPane().add(myButton);
myButton.addActionListener(this);
setSize(400,400);
setVisible(true);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent e)
{
(how can I pass this "myLabel.getText()" value to class A when
this action performed?)
}
}
Can anybody help me finish this little program? Thanks in advance!
You need to expose the value in text field with a method in class B. Then class A can call that method. What it actually sounds like though is that class A (or something else) should be a ActionListener for your button.
However, a bigger problem is that you don't have a text field you just have a label in class B. This code is a good reason why you shouldn't use a GUI builder, especially when learning Swing.
Some reading:
http://docs.oracle.com/javase/tutorial/uiswing/components/textfield.html
http://docs.oracle.com/javase/tutorial/uiswing/events/
I often make an "App" class that ties all my GUI-builder-built components together. Any GUI builder worth anything lets you add getters to the generated source code. Add some getters to the GUI-built components to retrieve key elements of the GUI, then let the App class use the getters to interact with the components as necessary. This won't win any MVC/MVVM/MVP design awards, but it gets the job done, which ought to count for something.
public class App {
private B _b;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
App app = new App();
app.run();
}
});
}
void run() {
_b = new B();
_b.getMainButton().addActionListener(new MainButtonListener());
_b.setVisible(true);
}
private void handleMainButtonClicked() {
String mainText = _b.getMainTextArea().getText();
System.out.println("Button clicked; main text = " + mainText);
}
public class MainButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
handleMainButtonClicked();
}
}
}
public class B extends JFrame {
private JPanel _contentPane;
private JTextArea _jTextArea;
private JButton _jButton;
public B() {
initComponents();
}
private void initComponents() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 400);
_contentPane = new JPanel();
setContentPane(_contentPane);
_jTextArea = new JTextArea();
_contentPane.add(_jTextArea, BorderLayout.CENTER);
_jButton = new JButton("My Button");
_contentPane.add(_jButton, BorderLayout.SOUTH);
}
public JButton getMainButton() {
return _jButton;
}
public JTextComponent getMainTextArea() {
return _jTextArea;
}
}
Basically what I want to do is get a start button to initiate a method running in another class and acting on another object.
My code for the listener:
button1a.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent event) {
// Figure out how to make this work
//sim.runCastleCrash();
}
} );
My code for the other class:
public static void main(String[] args) {
CastleCrash sim;
sim = new CastleCrash();
}
and
public void runCastleCrash() {
System.out.println("Castle Crash is beginning...");
//Other method parts here to be added
}
I get the feeling this can't be too hard, but I'm missing a piece.
One way to reference things in an anonymous class is using the final keyword:
public static void main(String[] args) {
final Object thingIWantToUse = "Hello";
JButton button = new JButton("Click");
button.addActionListener(new ActionListener() {
#Override public void actionPerformed(ActionEvent e) {
System.out.println(thingIWantToUse);
}
});
JFrame frame = new JFrame();
frame.setLayout(new FlowLayout());
frame.add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
Alternatively, you can access members (variables or methods) of an enclosing type:
public class ActionListenerDemo2 {
private final JFrame frame = new JFrame();
private Object thingIWantToUse = "Hello";
public ActionListenerDemo2() {
JButton button = new JButton("Click");
button.addActionListener(new ActionListener() {
#Override public void actionPerformed(ActionEvent e) {
thingIWantToUse = "Goodbye";
System.out.println(thingIWantToUse);
}
});
frame.setLayout(new FlowLayout());
frame.add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
new ActionListenerDemo2().frame.setVisible(true);
}
}
I've had the same problem like you and this is how i solved it.
You can either make your object final (final CastleCrash sim = new CastleCrash();), but i didn't want to do that, or you can make something like a setter method to run the method in your other class:
My code for the listener class:
button1a.addActionListener(new ActionListener()
{
public void actionPerformed (ActionEvent event)
{
//How to make this work ?
//Like this:
runCC();
}
});
public void runCC()
{
CastleCrash sim = new CastleCrash();
sim.runCastleCrash();
}
My code for the other class:
public void runCastleCrash()
{
System.out.println("Castle Crash is beginning...");
//Other method parts here to be added
}
Hope this is helpful, good luck ! :)
McDowell already answers practically with good examples on how to access variables from event listeners (or anonymous inner classes in general). There is however a more general Sun resource on Event Listeners in Swing that is canonical and a good overview of all the caveats to take into account when writing them.
Somehow you need a reference to your CastleCrash object available to call from your actionListener.
You probably want to subclass JFrame, or whatever is containing your JButton such that it has your both your main method and a CastleCrash property that can then be referenced from your anonymous inner class Actionlistener.
BUT - be careful, you look like you are calling what will be a long running method from within the GUI event thread (where the action listener will called). This is generally a bad idea, you will case your GUI to become unresponsive.
See http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html especially the bit on SwingWorker class for ideas on how to avoid that problem.