I have a complicated GUI with lot of components (JButtons, JLabels, JComboBoxes, JSpinners, etc). That's why I have to split it on several classes (add components to JPanels, this JPanels add to bigger JPanels, this JPanels add to JTabbedPane, and JTabbedPane add to JFrame).
Depend on user choises and filling in data some components enabled or disabled or get some value and set not editable (in a word - interact). It's easy to done and worked properly, if components (which are interact) are in the same class, but if only it are in different classes - any results... AAA!!!
I made simple example to explane what I need. There are four classes. First one create JFrame and add JTabbedPane:
public class MainFrame extends JFrame {
MainFrame() {
super("MainFrame");
go();
}
public void go() {
Tabs tabs = new Tabs();
getContentPane().add(tabs);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500, 300);
setVisible(true);
}
public static void main(String[] args) {
MainFrame frame = new MainFrame();
}
}
The second class create JTabbedPane and add two JPanels as tabs. Second tab.setEnabledAt(1, false):
public class Tabs extends JTabbedPane {
public Tabs() {
go();
}
public void go() {
TabData data = new TabData();
add(" Data ", data);
TabCalculation calculation = new TabCalculation();
add("Calculation", calculation);
setEnabledAt(1, false);
}
}
The third class create JPanel with JComboBox:
public class TabData extends JPanel {
public TabData() {
go();
}
JComboBox someData;
public void go() {
String type[] = { " ", "Type 1", "Type 2", "Type 3" };
someData = new JComboBox(type);
add(someData);
someData.addActionListener(new DataListener());
}
public class DataListener implements ActionListener {
public void actionPerformed(ActionEvent ev) {
if (someData.getSelectedIndex() > 0) {
Tabs tabs = new Tabs();
tabs.setEnabledAt(1, true);
}
}
}
}
... and fourth class create some JPanel. Second tab with this JPanel disabled. When user set some value in JComboBox (selectedIndex>0) - tab have to enabled. But Tabs tabs = new Tabs(); tabs.setEnabledAt(1, true); didn't help...
How can I do that? PLEASE HELP!!! I can't sleep... I can't work... I always thinking about it and try to find out a solution...
When user set some value in JComboBox (selectedIndex>0) - tab have to
enabled.
If you need to have all of these classes split, then I would suggest you make this change in your 3rd class:
public class TabData extends JPanel {
JComboBox someData;
...
// Get rid of DataListener class and add this public method instead:
public void addActionListenerToComboBox(ActionListener listener) {
someData.addActionListener(listener);
}
}
And make this change in your 2nd class:
public class Tabs extends JTabbedPane {
public Tabs() {
go();
}
public void go() {
TabData data = new TabData();
data.addActionListenerToComboBox(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JComboBox comboBox = (JComboBox)e.getSource();
boolean enableSecondTab = comboBox.getSelectedIndex() > -1;
setEnabledAt(1, enableSecondTab);
}
});
add(" Data ", data);
TabCalculation calculation = new TabCalculation();
add("Calculation", calculation);
setEnabledAt(1, false);
}
}
Take a look to EventObject.getSource() javadoc for more details.
Related
I've tried to apply the Observable/Observer pattern but there is something wrong with my code when I try to change a the textfield of a JTextPane.
I've got 3 classes, Play, Controller and SecondWindow here are a sample of their code.
public class Play() {
Controller c = new Controller();
SecondWindow sw = new SecondWindow();
c.addObserver(sw)
c.setText("blabla");
}
My class Controller:
public class Controller extends Observable(){
private String text ="";
private static Controller getInstance() {
if (instance == null) {
instance = new Controller();
}
return instance;
}
public void setText(String s) {
text = s;
setChanged();
notifyObservers();
}
}
and SecondWindow:
public class SecondWindow extends JFrame implements Observer{
private JPanel contentPane;
private Controller c;
private JTextPane txt = new JTextPane();
public SecondWindow () {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
SecondWindow frame = new SecondWindow();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public SecondWindow() {
initComponents();
createEvents();
c = Controller.getInstance();
}
public void initComponents() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(1000, 0, 300,500);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
txt.setBounds(0, 0, 280, 460);
txt.enable(false);
contentPane.add(txt);
}
public void update(Observable arg0 , Object arg1){
// Things to change here
}
I can't manage to put the variable c in the textField (like a txt.setText(c.getText) instruction). I'm sure that it reads the method update, but I don't know how to make sure it works.
Hint: Per the Observerable API the notifyObservers method has an overload that accepts any object as a parameter:
public void notifyObservers(Object arg)
This can even be a String. And as per the Observer API, this object is then passed into the update method in the observer, and you can use it there.
void update(Observable o,
Object arg)
arg - an argument passed to the notifyObservers method.
Separate side issue here:
contentPane.setLayout(null);
For most Swing aficionados, seeing this is like hearing nails on a chalkboard -- it's painful. While null layouts and setBounds() might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one. Instead you will want to study and learn the layout managers and then nest JPanels, each using its own layout manager to create pleasing and complex GUI's that look good on all OS's.
Side issue number two: your code is not Swing thread safe, since the Swing GUI could very well be notified by the observable off of the Swing event dispatch thread or EDT. While it is not likely to cause frequent or serious problems with this simple program, in general it would be better to use a SwingPropertyChangeSupport and PropertyChangeListeners rather than Observer / Observable if you can.
Next Side Issue
This:
public class Controller extends Observable(){
isn't compilable / kosher Java. Same for the duplicate parameter-less constructors for the SecondWindow class. Yes, we know what you're trying to do, but it's hard enough trying to understand someone else's code, you really don't want to make it harder by posting kind-of sort-of uncompilable code, trust me.
For example, something simple could be implemented in Swing using PropertyChangeListeners, like so:
import java.util.concurrent.TimeUnit;
public class Play2 {
public static void main(String[] args) {
Model2 model2 = new Model2();
View2 view2 = new View2();
new Controller2(model2, view2);
view2.show();
for (int i = 0; i < 10; i++) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
// one of the few times it's OK to ignore an exception
}
String text = String.format("Counter Value: %d", i);
model2.setText(text);
}
}
}
import java.beans.PropertyChangeListener;
import javax.swing.event.SwingPropertyChangeSupport;
public class Model2 {
private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(this);
public static final String TEXT = "text"; // name of our "bound" property
private String text = "";
public String getText() {
return text;
}
public void setText(String text) {
String oldValue = this.text;
String newValue = text;
this.text = text;
pcSupport.firePropertyChange(TEXT, oldValue, newValue);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(listener);
}
public void addPropertyChangeListener(String name, PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(name, listener);
}
public void removePropertyChangeListener(String name, PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(name, listener);
}
}
import javax.swing.*;
public class View2 {
private JPanel mainPanel = new JPanel();
private JTextField textField = new JTextField(10);
public View2() {
textField.setFocusable(false);
mainPanel.add(new JLabel("Text:"));
mainPanel.add(textField);
}
public JPanel getMainPanel() {
return mainPanel;
}
public void setText(String text) {
textField.setText(text);
}
public void show() {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("View");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(getMainPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
public class Controller2 {
private Model2 model2;
private View2 view2;
public Controller2(Model2 model2, View2 view2) {
this.model2 = model2;
this.view2 = view2;
model2.addPropertyChangeListener(Model2.TEXT, new ModelListener());
}
private class ModelListener implements PropertyChangeListener {
#Override
public void propertyChange(PropertyChangeEvent pcEvt) {
view2.setText((String) pcEvt.getNewValue());
}
}
}
I've been trying to call a method which displays frames in an EditorWindow, when pushing a button in the ExplorerWindow.
There are 3 modules:
AppEditorAPI which contains this interface
package org.app.AppEditorAPI;
public interface Displayer {
public void Display();
}
AppEditor which contains EditorTopComponent
#ServiceProvider(service=Displayer.class)
public final class EditorTopComponent extends TopComponent implements Displayer{
private JDesktopPane jdpDesktop=null;
private int openFrameCount = 0;
...
protected void createFrame() {
MyInternalFrame frame = new MyInternalFrame();
frame.setVisible(true);
jdpDesktop.add(frame);
try {
frame.setSelected(true);
} catch (java.beans.PropertyVetoException e) {
}
}
class MyInternalFrame extends JInternalFrame {
int xPosition = 30, yPosition = 30;
public MyInternalFrame() {
super("IFrame #" + (++openFrameCount), true, // resizable
true, // closable
true, // maximizable
true);// iconifiable
setSize(300, 300);
setLocation(xPosition / openFrameCount, yPosition / openFrameCount);
// Add some content:
add(new JLabel("hello IFrame #" + (openFrameCount)));
}
}
public void Display(){
jdpDesktop = new JDesktopPane();
createFrame(); // Create first window
createFrame(); // Create second window
createFrame(); // Create third window
//Add the JDesktop to the TopComponent
add(jdpDesktop);
}
}
And AppExplorer which contains ExplorerTopComponent
public final class ExplorerTopComponent extends TopComponent {
...
private void initComponents() {
B_Display = new javax.swing.JButton();
..
}
private void B_DisplayActionPerformed(java.awt.event.ActionEvent evt) {
Displayer D = Lookup.getDefault().lookup(Displayer.class);
D.Display();
}
...
}
Below, are links to the project zip file.
http://dl.free.fr/k2Z6DRLrW
http://www.fileswap.com/dl/lCeFPcUfbg/
After doing some tests. I found that I can't change (add, remove or edit) the variables or properties of the EditorTopComponent.
Like in this case, these two lines;
public void Display(){
jdpDesktop = new JDesktopPane();
...
add(jdpDesktop);
}
Are not executed as they should, that's why after the execution, the EditorTopComponent.jdpDesktop still was equal to null and wasn't added to the EditorTopComponent.
Knowing what I want to do, can someone please guide me on the right track ?
At last, 'made It work... see that's what happens when you avoid reading the books :P
I'm posting the solution if anyone's facing the same issue.
As I mentioned when editing my question, knowing that modifications are not allowed through the lookup, you can either use the InstanceContent variable which can be modified in the lookup, or, use the WindowManager to fitch the EditorTopComponent and call the Display() method.
Good luck
Hi well my code so far does something like this: Click a button, opens a combobox. I want to select an option on the ComboBox and depending on which option is picked i want to open another combobox using getSelectIndex().
Here are parts of my code which are relevant. I know I have to make the other comboboxes not visible or removed but at the moment I'm just trying to make a combobox appear. As you can see i have inserted the actionlistener for the button which works and opens the combobox.however when selecting a string in the combobox no event occurs. However when I run it, no comboboxes appear.
public class Work extends JFrame {
// variables for JPanel
private JPanel buttonPanel;
private JButton timeButton;
public Work()
{
setLayout(new BorderLayout());
buttonPanel = new JPanel();
buttonPanel.setBackground(Color.RED);
buttonPanel.setPreferredSize(new Dimension(400, 500));
add(buttonPanel,BorderLayout.WEST);
timeButton = new JButton("Time");
buttonPanel.add(timeButton);
buttontime clickTime = new buttontime(); // event created when time button is clicked
timeButton.addActionListener(clickTime);
Time timeObject = new Time();
timeObject.SelectTime();
buttontime2 selectDest = new buttontime2();
timeObject.getAirportBox().addActionListener(selectDest);
}
public class buttontime implements ActionListener { //creating actionlistener for clicking on timebutton to bring up a combobox
public void actionPerformed(ActionEvent clickTime) {
Time timeObject = new Time();
timeObject.SelectTime();
add(timeObject.getTimePanel(),BorderLayout.EAST);
timeObject.getTimePanel().setVisible(true);
timeObject.getTimePanel().revalidate() ;
timeObject.getAirportBox().setVisible(true);
}
}
public class buttontime2 implements ActionListener{
public void actionPerformed(ActionEvent selectDest) {
Time timeObject = new Time();
timeObject.SelectTime();
if(timeObject.getAirportBox().getSelectedIndex() == 1) {
timeObject.getEastMidBox().setVisible(true);
}
else if(timeObject.getAirportBox().getSelectedIndex() == 2) {
timeObject.getBirmBox().setVisible(true);
}
else if(timeObject.getAirportBox().getSelectedIndex() == 3) {
timeObject.getMancbox().setVisible(true);
}
else if(timeObject.getAirportBox().getSelectedIndex() == 4) {
timeObject.getHeathBox().setVisible(true);
}
}
}
public static void main (String args[]) {
events mainmenu = new events(); //object is created
mainmenu.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainmenu.setSize(800,500);
mainmenu.setVisible(true);
mainmenu.setLayout(new BorderLayout());
mainmenu.setTitle("Learning how to use GUI");
mainmenu.setBackground(Color.BLUE);
mainmenu.setResizable(false);
}
}
my other class TIME
import javax.swing.JOptionPane;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Time
{
private JComboBox timeAirportbox;//comboboxes declared
private JComboBox eastMidbox;
private JComboBox mancBox;
private JComboBox heathBox;
private JComboBox birmBox;
private String[] airport = {"","EM", "Bham", "Manc", "Heath"};//array of airports declared
private String[] destination = {"","NY", "Cali", "FlO", "MIAMI", "Tokyo"};//array of destinations declared
private JPanel timePanel;
public void SelectTime() {
//combobox objects created
timePanel = new JPanel();
timePanel.setBackground(Color.BLUE);
timePanel.setPreferredSize(new Dimension(400, 400));
timeAirportbox = new JComboBox(airport);//array is inserted into the JComboBox
timePanel.add(timeAirportbox);
timeAirportbox.setVisible(false);
eastMidbox = new JComboBox(destination);
timePanel.add(eastMidbox);
eastMidbox.setVisible(false);
mancBox = new JComboBox(destination);
timePanel.add(mancBox);
mancBox.setVisible(false);
heathBox = new JComboBox(destination);
timePanel.add(heathBox);
heathBox.setVisible(false);
birmBox = new JComboBox(destination);
timePanel.add(birmBox);
birmBox.setVisible(false);
}
public JPanel getTimePanel() {
return timePanel;
}
public JComboBox getAirportBox() {
return timeAirportbox;
}
public JComboBox getEastMidBox() {
return eastMidbox;
}
public JComboBox getMancbox() {
return mancBox;
}
public JComboBox getHeathBox() {
return heathBox;
}
public JComboBox getBirmBox() {
return birmBox;
}
}
The Time object that is built in Work constructor is not used:
Time timeObject = new Time();
timeObject.SelectTime();
buttontime2 selectDest = new buttontime2();
timeObject.getAirportBox().addActionListener(selectDest);
As you are only applying the action listener selectedDest to the combobox of that timeObject, which is not used, then the listener will never be called.
You can do two things to make it work:
Move the code that creates the listener and assign it to the combox in the first listener buttontime
Create the Time object only once and store it as a member of your Work instance. As your listener is a non-static inner classes of the Work class, it will be able to use it instead of creating a new Time object.
Edit: I didn't see that in your second listener, you were AGAIN building a new Time object. This object is really a different one than the one you have created earlier, so modifying one will not affect the other. You really should create the Time object once and store it as a member variable of your Work class, and then use this object in your listeners instead of recreating it.
To be clear, do it like this:
public class Work extends JFrame {
// ...
private Time timeObject;
public Work() {
// ...
timeObject = new Time();
timeObject.SelectTime();
buttontime2 selectDest = new buttontime2();
timeObject.getAirportBox().addActionListener(selectDest);
}
public class buttontime implements ActionListener {
public void actionPerformed(ActionEvent clickTime) {
// use timeObject, don't create it and don't call SelectTime()
// example:
add(timeObject.getTimePanel(),BorderLayout.EAST);
// ....
}
}
public class buttontime2 implements ActionListener {
public void actionPerformed(ActionEvent clickTime) {
// use timeObject, don't create it and don't call SelectTime()
}
}
}
Also to note:
You should not extends JFrame, there is no reason to do so. Refactor your code so that your frame is just a member variable of your Work class.
Follow Java standard code conventions, especially use case properly with class names: buttonlistener should be ButtonListener, and method should start with lowercase: SelectTime should be selectTime.
how do you trap the event before the new tab is switched to?
In every Tab I have JTable and i do something with it's data(delete, add , update). I would like to do data validation(save or cancel changes) before switching to the new tab. I use Java 1.5.
class ViewPanel extends JPanel
{
private void Components() {
setPreferredSize(new Dimension(700, 400));
tabbedPane.addTab("DC", ANSFER.getIcon(),new DcTabPanel(this), "DC");
tabbedPane.addTab("PC", THUMB4.getIcon(),new PcTabPanel(this), "PC");
tabbedPane.addChangeListener(this);
add(tabbedPane);
}
public void stateChanged(ChangeEvent e) {
}
}
JTabbedPane is backed by a SingleSelectionModel. If you extend DefaultSingleSelectionModel, you can override the setSelectedIndex method and implement your logic.
// in new selection model:
public void setSelectedIndex(int index) {
// do pre-switch things here
super.setSelectedIndex(index);
}
// in ViewPanel, on tabbedPane create:
tabbedPane.setModel(newSelectionModel);
The reason you can't simply use a ChangeListener is because that fires on change. By extending the selection model, you fire before the tab change.
You can prevent tab switching by extending JTabbedPane and override setSelectedIndex(int). Here is a small example illustrating that. It simply prevents from switching between non-contiguous tabs:
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
public class Test2 {
private static class BlockingTabbedPane extends JTabbedPane {
public static interface TabSwitchAllower {
public boolean allowTabSwitch(int from, int to);
}
private TabSwitchAllower allower;
public BlockingTabbedPane(TabSwitchAllower allower) {
super();
this.allower = allower;
}
#Override
public void setSelectedIndex(int index) {
if (allower == null || allower.allowTabSwitch(getSelectedIndex(), index)) {
super.setSelectedIndex(index);
}
}
}
protected static void initUI() {
final JFrame frame = new JFrame("test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BlockingTabbedPane.TabSwitchAllower allower = new BlockingTabbedPane.TabSwitchAllower() {
#Override
public boolean allowTabSwitch(int from, int to) {
if (Math.abs(from - to) == 1) {
return true;
} else {
JOptionPane.showMessageDialog(frame, "You can only switch between contiguous tabs");
}
return false;
}
};
JTabbedPane tabbedPane = new BlockingTabbedPane(allower);
for (int i = 0; i < 10; i++) {
tabbedPane.addTab("Tab-" + i, new JLabel("Hello tab " + i));
}
frame.add(tabbedPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
initUI();
}
});
}
}
java actionlistener on a tab
How to Write a Change Listener (Oracle Docs)
JTabbedPane API (Oracle Docs)
Those two links should help you out. I haven't really worked with tabbedPanes, but I am assuming that the getSelectedComponent() will return the current selected tab. So you can have a handle to the currentTab which will be set during instantiation. Then you can have something like this.
class TabListener implements ChangeListener {
public void stateChanged(ChangeEvent e) {
// Replace JSlider with whatever your tab's data type is
JSlider source = (JSlider)e.getSource();
// Use the 'currentTab' handle to do what you want.
currentTab = getSelectedComponent();
// I'm assuming that the 'selected component' by the time this stuff
// runs is going to be the new selected tab.
}
}
I am not too confident about my answer, but I certainly hope that this will point you towards the right direction! Please say if you need any clarification or anything! If I happen to discover anything that I think might be useful, I'll be certain to edit my answer!
I am working on an assignment, and I need to enter an SQL Query in a textfield. The user can either press the custom 'execute query' button, or they can press the enter key. When either of these are used, it is to trigger an ActionListener (no other listener is allowed). Is it as simple as writing:
if (e.getSource()=='querybutton' || e.getSource=='enter')
Or is there more to it than this?
As I said, it is a simple question (I know).
edit:
I would write this bit in my ActionPerformed as:
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==gui.executeQueryButton || e.getSource()==gui.enter)
{
String query = gui.queryText.getText();
//more code to follow
}
}
e.getSource() actually returns the object responsible for firing the event (not the name of the variable you used when creating the control). In this case, your button. You could in principle compare e.getSource() with the actual button instances. However, are you actually adding this action listener to buttons other than those two? Presumably you'd only have to add this listener to the two buttons for which you want this behavior -- in which case you wouldn't have to have this if check.
" Is it as simple as writing:
if (e.getSource()=='querybutton' || e.getSource=='enter')"
It's not simple to write this, but rather it is wrong to write it.
For one you don't want to compare Strings with ==, for another, you don't declare Strings with single quotes, and for a third, the enter key is not obtained in this way, but rather by adding the appropriate ActionListener object to the JTextField itself, and finally there should be in a single ActionListener class that handles this action, so the if block is completely unnecessary. This can probably be best done with a small inner private ActionListener class. You'd then create one object of this class and add it as an ActionListener for the querybutton and for the JTextField.
edit 1:
A more complete example of what I mean is shown below, a demo class that has a private inner handler class:
import java.awt.event.*;
import javax.swing.*;
public class ActionListenerEg extends JPanel {
private JButton queryButton = new JButton("Query");
private JTextField textField = new JTextField("hello", 20);
public ActionListenerEg() {
QueryListener qListener = new QueryListener();
queryButton.addActionListener(qListener);
textField.addActionListener(qListener);
add(queryButton);
add(textField);
}
private class QueryListener implements ActionListener {
public void actionPerformed(ActionEvent arg0) {
String textInField = textField.getText();
System.out.println("Use text in field, \"" + textInField + "\" to call SQL query in a background SwingWorker thread.");
}
}
private static void createAndShowUI() {
JFrame frame = new JFrame("ActionListenerEg");
frame.getContentPane().add(new ActionListenerEg());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
The ActionListener is fired either by pressing the button or by pressing enter from within the JTextField. I'd then have in my control class, code that is called inside of the actinoPerformed method.
edit 2: Having most handler or "control" code in its own Handler or Control class can be a good idea, but it doesn't have to implement ActionListener interface itself, but rather just have the code that will be called from within the ActionListener codes. For example, here I try to put all the handler code in its own class. It will have different methods that are called for various situations. e.g.,
import java.awt.Component;
import java.awt.event.*;
import javax.swing.*;
public class ActionListenerEg extends JPanel {
private ActionListenerHandler handler;
private JButton queryButton = new JButton("Query");
private JButton displayButton = new JButton("Display");
private JTextField textField = new JTextField("hello", 20);
// pass in handler or handler
public ActionListenerEg(final ActionListenerHandler handler) {
this.handler = handler;
QueryListener qListener = new QueryListener();
queryButton.addActionListener(qListener);
textField.addActionListener(qListener);
displayButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (handler != null) {
handler.displayActionPerformed(e);
}
}
});
add(queryButton);
add(textField);
add(displayButton);
}
private class QueryListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (handler != null) {
String textInField = textField.getText();
handler.doQueryAction(e, textInField);
}
}
}
private static void createAndShowUI() {
ActionListenerHandler handler = new ActionListenerHandler();
JFrame frame = new JFrame("ActionListenerEg");
frame.getContentPane().add(new ActionListenerEg(handler));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
class ActionListenerHandler {
public void displayActionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog((Component) e.getSource(), "Display things!");
}
public void doQueryAction(ActionEvent e, String textInField) {
String text = "We will use \"" + textInField + "\" to help create and run the SQL Query";
JOptionPane.showMessageDialog((Component) e.getSource(), text);
}
}
Please ask questions if it's clear as mudd, or if anything is wrong.