PDA

View Full Version : Java: enabling/disabling buttons based on states




toddburch
Mar 26, 2007, 11:48 PM
I have small app that has two buttons on the first TAB: CONNECT and DISCONNECT. On intial entry, the app needs to CONNECT, and there is nothing to DISCONNECT. Once connnected, I want to allow it to DISCONNECT, but not connect. Once disconnected, it can CONNECT again, and so on.

On the second TAB, there is a SUBMIT button and a JTextArea. With my current logic, if "connected", then SUBMIT is enabled.

I want to add additional logic here as well. If there is no text in the JTextArea, then the SUBMIT button should be disabled, regardless of the connection status.

Now, if you look at my code, you'll see I made all concerned JButtons class variables. I'm sure there is a better way, but I'm not sure how to access each button in the Adapter class's actionPerformed methods I'm using at the bottom of the listing. If someone could point me in the right direction here, I could probably figure out the rest.

Thanks again for your time.

Todd

Here's the code (file name MySLO.java)

// My Simpler Lay Out Test.
public class MySLO extends javax.swing.JFrame {

static javax.swing.JTextArea myText ;
static javax.swing.JButton buttonSubmit ;
static javax.swing.JButton buttonConnect;
static javax.swing.JButton buttonDisconnect ;

// Create a window with all the GUI stuff, and display it.
public static void main(String[] args) {
javax.swing.JFrame win = new MySLO() ;
win.setVisible(true) ; // make window appear
}

// This is the GUI window maker. It builds the buttons, does the layout,
// registers for events, etc...
public MySLO() {
super("JTabbedLayout") ; // This is the window title

// Get the JFrame's container.
java.awt.Container content = this.getContentPane() ;
this.setSize(700,400) ;

// Connect and Disconnnect Buttons.
buttonConnect = new javax.swing.JButton("Connect") ;
buttonConnect.addActionListener(new ButtonConnect(this) ) ;
content.add(buttonConnect) ;

buttonDisconnect = new javax.swing.JButton("Disconnect") ;
buttonDisconnect.addActionListener(new ButtonDisconnect(this) ) ;
content.add(buttonDisconnect) ;

myText = new javax.swing.JTextArea(10,45) ;
myText.setLineWrap(false) ;
myText.setTabSize(3) ;
myText.setText("") ;

javax.swing.JScrollPane jsc = new javax.swing.JScrollPane(myText) ;
jsc.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS) ;
jsc.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED) ;

javax.swing.JButton buttonClear = new javax.swing.JButton("Clear") ;
buttonClear.addActionListener(new ButtonClear(this) ) ;
content.add(buttonClear) ;

buttonSubmit = new javax.swing.JButton("Submit") ;
buttonSubmit.addActionListener(new ButtonSubmit(this) ) ;
content.add(buttonSubmit);

this.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE) ; // Close app when RED X is clicked.

javax.swing.JPanel pan1 = new javax.swing.JPanel() ;
pan1.add(buttonConnect) ;
pan1.add(buttonDisconnect) ;

javax.swing.JPanel pan2 = new javax.swing.JPanel() ;
pan2.add(jsc) ;
pan2.add(buttonSubmit) ;
pan2.add(buttonClear) ;

//javax.swing.JPanel pan3 = new javax.swing.JPanel() ;
//pan3.add(new javax.swing.JLabel("Output...") );

javax.swing.JTabbedPane jtp = new javax.swing.JTabbedPane() ; ;

jtp.addTab("Connections" , pan1 ) ;
jtp.addTab("Edit SQL", pan2 ) ;

content.add(jtp) ; // add the JTabbedPane to the container

this.pack() ; // Resize the window as needed.

// Center the Dialog on the screen.
java.awt.Dimension screen = java.awt.Toolkit.getDefaultToolkit().getScreenSize() ;
int x = (screen.width - this.getWidth() ) / 2 ;
int y = (screen.height - this.getHeight() ) / 2 ;
setBounds(x,y,this.getWidth(),this.getHeight()) ;
}


// Adapter Classes - to separate the GUI from the application logic (not that there IS any appl. logic yet...

class ButtonClear implements java.awt.event.ActionListener {
MySLO data ;
ButtonClear (MySLO data ) {
this.data = data ;
}
public void actionPerformed( java.awt.event.ActionEvent ae) {
data.myText.setText("") ;
System.out.println("Input data has been cleared") ;
buttonSubmit.setEnabled(false) ;
}
}

class ButtonSubmit implements java.awt.event.ActionListener {
MySLO data ;
ButtonSubmit (MySLO data ) {
this.data = data ;
buttonSubmit.setEnabled(false) ;
}
public void actionPerformed( java.awt.event.ActionEvent ae) {
System.out.println("Submit Button") ;
}
}

class ButtonConnect implements java.awt.event.ActionListener {
MySLO data ;
ButtonConnect (MySLO data ) {
this.data = data ;
buttonConnect.setEnabled(true) ;
}
public void actionPerformed( java.awt.event.ActionEvent ae) {
System.out.println("Connect Button") ;
buttonDisconnect.setEnabled(true) ;
buttonConnect.setEnabled(false) ;
buttonSubmit.setEnabled(true) ;
}
}

class ButtonDisconnect implements java.awt.event.ActionListener {
MySLO data ;
ButtonDisconnect (MySLO data ) {
this.data = data ;
buttonDisconnect.setEnabled(false) ;
}
public void actionPerformed( java.awt.event.ActionEvent ae) {
System.out.println("Disconnect Button") ;
buttonConnect.setEnabled(true) ;
buttonDisconnect.setEnabled(false) ;
buttonSubmit.setEnabled(false) ;
}
}
}



hsvmoon
Mar 27, 2007, 04:10 PM
Declare the listeners inside the class that defines the buttons. Leave out the constructor for the listeners unless you really need it. Create the buttons and listeners. Add the listeners to the buttons. In the inner class listeners reference the buttons by name. Do not use the keyword "this". Inner classes can see the variables of outer classes. The GUI builder in an IDE makes this very easy.

toddburch
Mar 28, 2007, 09:14 AM
I believe you are correct. I'm digging deeper into my manuals, and when I get this worked out, I'll repost. Slowly, slowly, this is sinking in.

Thanks!

T-Stex
Mar 29, 2007, 01:54 AM
Do not use the keyword "this". Inner classes can see the variables of outer classes. The GUI builder in an IDE makes this very easy.

Although I am not a software engineer by any stretch, I sometimes find that using "this" can provide an extra level of readability to my code, and provides for more consistency in the code. I wouldn't necessarily take out every instance of "this" in the code, especially when calling the method within the same block as other methods acting on other objects. I think that it's up to you to decide if you need it or not, depending on who will be reading your code.

hsvmoon
Mar 29, 2007, 10:36 AM
Although I am not a software engineer by any stretch, I sometimes find that using "this" can provide an extra level of readability to my code, and provides for more consistency in the code. I wouldn't necessarily take out every instance of "this" in the code, especially when calling the method within the same block as other methods acting on other objects. I think that it's up to you to decide if you need it or not, depending on who will be reading your code.

If you use the keyword "this" to try to access the members of an outer class from within an inner class you will get a compiler error. That is because the inner class does not have that member value. You will be able to access the outer classes members by direct reference. In general it is good practice to use the keyword "this" to reference class level members from within that class, but in this case you are not trying to access values in the same class.