I am a computer scientist in my first year of my apprenticeship.
In the beginning we started with procedural Java programming, now we have to learn the object oriented Java. To begin with that, we have to program a GUI with some features and something to save some Strings like in a Database.
Anyway, I'm not there yet. I'm still stuck at creating and Structure the GUI. It has everything inside that it needs, but the structure I'm trying to get does not really work.
So here's what I got:
TestGUI.Java
import javax.swing.*;
public class TestGui {
public static void main(String[] args){
ModulGui GUI = new ModulGui();
ImageIcon img = new ImageIcon("icon.png");
GUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GUI.setSize(250,350);
GUI.setIconImage(img.getImage());
GUI.setLocationByPlatform(true);
GUI.setResizable(false);
GUI.setVisible(true);
}
}
ModulGui.java
import javax.swing.*;
import java.awt.*;
import java.security.PrivateKey;
public class ModulGui extends JFrame {
private final JLabel LabelModulID;
private final JLabel LabelModulName;
private final JLabel LabelStartDatum;
private final JTextField TextFeldModulId;
private final JTextField TextFeldModulName;
private final JTextField TextFeldStartDatum;
private final JButton ButtonHinzufuegen;
private final JButton ButtonEntfernen;
private final JButton ButtonAlleAusgeben;
public ModulGui(){
super("Modulliste");
setLayout(new FlowLayout());
GridBagConstraints GuiGrid = new GridBagConstraints();
LabelModulID = new JLabel("Modul ID");
LabelModulID.setToolTipText("Bitte Modul ID eintragen.");
GuiGrid.gridx = 0;
GuiGrid.gridy = 1;
add(LabelModulID);
LabelModulName = new JLabel("Modulname");
LabelModulName.setToolTipText("Bitte Modulnamen eintragen");
GuiGrid.gridx = 0;
GuiGrid.gridy = 2;
add(LabelModulName);
LabelStartDatum = new JLabel("Startdatum");
LabelStartDatum.setToolTipText("Startdatum des Moduls eintragen");
GuiGrid.gridx = 0;
GuiGrid.gridy = 3;
add(LabelStartDatum);
TextFeldModulId = new JTextField(25);
GuiGrid.gridx = 0;
GuiGrid.gridy = 4;
add(TextFeldModulId);
TextFeldModulName = new JTextField(25);
GuiGrid.gridx = 0;
GuiGrid.gridy = 5;
add(TextFeldModulName);
TextFeldStartDatum = new JTextField(25);
GuiGrid.gridx = 0;
GuiGrid.gridy = 6;
add(TextFeldStartDatum);
ButtonHinzufuegen = new JButton("Hinzufügen");
GuiGrid.gridx = 0;
GuiGrid.gridy = 7;
add(ButtonHinzufuegen);
ButtonEntfernen = new JButton("Entfernen");
GuiGrid.gridx = 0;
GuiGrid.gridy = 8;
add(ButtonEntfernen);
ButtonAlleAusgeben = new JButton("Alle Ausgeben");
GuiGrid.gridx = 0;
GuiGrid.gridy = 9;
add(ButtonAlleAusgeben);
}
}
Sorry Maybe the Problem is really easy, but like I said I'm pretty new to programing :D
I also tried it with setBounds and setLayout(null)... Well didn't really work either.
I want to structure my Code as the following:
LabelModulID
TextFeldModulID
LabelModulName
TextFeldModulName
LabelStartDatum
TextFeldStartDatum
ButtonHinzufuegen
ButtonEntfernen
ButtonAlleAusgeben
Do you guys have an idea of how I could do this?
And does someone know how I could use Objects or something else to store some Modules (Module) like in a Database. Like the class Modulelist and Module.
Thank you guys in advance!!
//Edit//
So that's the new code I got with your help. It doesn't look good, but it isn't bad for the second attempt:
import javax.swing.*;
import java.awt.*;
import java.security.PrivateKey;
public class ModulGui extends JFrame {
public final JPanel panelModulID = new JPanel();
public final JPanel panelModulName = new JPanel();
public final JPanel panelStartDatum = new JPanel();
public final JPanel panelButtons = new JPanel();
private final JLabel LabelModulID;
private final JLabel LabelModulName;
private final JLabel LabelStartDatum;
private final JTextField TextFeldModulId;
private final JTextField TextFeldModulName;
private final JTextField TextFeldStartDatum;
private final JButton ButtonHinzufuegen;
private final JButton ButtonEntfernen;
private final JButton ButtonAlleAusgeben;
public ModulGui(){
super("Modulliste");
setLayout(new FlowLayout(FlowLayout.CENTER));
LabelModulID = new JLabel("Modul ID");
LabelModulID.setToolTipText("Bitte Modul ID eintragen.");
panelModulID.add(LabelModulID);
LabelModulName = new JLabel("Modulname");
LabelModulName.setToolTipText("Bitte Modulnamen eintragen");
panelModulName.add(LabelModulName);
LabelStartDatum = new JLabel("Startdatum");
LabelStartDatum.setToolTipText("Startdatum des Moduls eintragen");
panelStartDatum.add(LabelStartDatum);
TextFeldModulId = new JTextField(25);
panelModulID.add(TextFeldModulId);
TextFeldModulName = new JTextField(25);
panelModulName.add(TextFeldModulName);
TextFeldStartDatum = new JTextField(25);
panelStartDatum.add(TextFeldStartDatum);
ButtonHinzufuegen = new JButton("Hinzufügen");
panelButtons.add(ButtonHinzufuegen);
ButtonEntfernen = new JButton("Entfernen");
panelButtons.add(ButtonEntfernen);
ButtonAlleAusgeben = new JButton("Alle Ausgeben");
panelButtons.add(ButtonAlleAusgeben);
add(panelModulID);
add(panelModulName);
add(panelStartDatum);
add(panelButtons);
}
}
And it gets me this:
Ok, i'll try to do it with a layout Manager... Which one did you use? I would have tried with GroupLayout.
Ah, therein lies a common error. Few, if any, good layouts are created using a single layout. Instead we usually combine them to create the needed GUI.
Take this layout for example:
It uses a GridBagLayout for the 'outer' part, but then puts a (JPanel with a) FlowLayout in the last row of that GBL to hold the buttons.
Here is the code used to put it together:
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class GUILayout {
private JComponent ui = null;
GUILayout() {
initUI();
}
public final void initUI() {
if (ui!=null) return;
ui = new JPanel(new GridBagLayout());
ui.setBorder(new EmptyBorder(4,4,4,4));
addLabelAndField("Module ID", 5, 0);
addLabelAndField("Module Name", 15, 1);
addLabelAndField("Start Datum", 10, 2);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridy = 3;
gbc.gridwidth = 2;
JPanel p = new JPanel();
ui.add(p, gbc);
p.add(new JButton("Hinzufuegen"));
p.add(new JButton("Entfernen"));
p.add(new JButton("Alle Ausgeben"));
}
private void addLabelAndField(String labelText, int fieldWidth, int row) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(5,5,5,5);
gbc.gridy = row;
gbc.anchor = GridBagConstraints.EAST;
ui.add(new JLabel(labelText), gbc);
gbc.gridx = 1;
gbc.anchor = GridBagConstraints.WEST;
ui.add(new JTextField(fieldWidth), gbc);
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = () -> {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
GUILayout o = new GUILayout();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
};
SwingUtilities.invokeLater(r);
}
}
At the moment, you're adding your GUI components directly to the JFrame. Instead, you need a JPanel to hold all your GUI components and then add that JPanel to your JFrame
For example:
JPanel panel = new JPanel();
panel.add(button1);
panel.add(button2);
panel.add(label1);
add(panel); // Adds panel to the JFrame
If you want to play around with specific layouts, you can check out the Java tutorials. There's also more information on how to use a JPanel in the Java documentation.
Related
I am working on an Uni Project using Java Swing. I want to create a statistics panel containing Temperature and other variables.
I have problems creating and showing the panel in the class MyPanel.
When I replace MyPanel p = new MyPanel() in the Class Main with the content of the method paintComponent in the Class MyPanel it works but not the other way around . I want to create the panel in a separate class and just call on it.
public class Main extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JPanel p = createAndShowGUI();
}
});
}
private static JPanel createAndShowGUI() {
System.out.println("Created GUI on EDT? "+
SwingUtilities.isEventDispatchThread());
JFrame f = new JFrame("Swing Demo");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyPanel p = new MyPanel();
f.add(p);
//f.add(new MyPanel());
f.pack();
f.setVisible(true);
return p;
}
}
public class MyPanel extends JPanel {
private JLabel TemperaturLabel ;
private JTextField Temperatur ;
private JLabel LuftfeuchtigkeitLabel;
private JTextField Luftfeuchtigkeit;
private JLabel luftdruckLabel;
private JTextField luftdruck;
private JLabel VorhersageLabel;
private JPanel Panel;
protected void paintComponent(Graphics g) {
TemperaturLabel = new JLabel("Temperatur: ");
Temperatur = new JTextField(2);
LuftfeuchtigkeitLabel = new JLabel("Luftfeuchtigkeit: ");
Luftfeuchtigkeit = new JTextField(3);
luftdruckLabel = new JLabel("Luftdruck: ");
luftdruck = new JTextField(4);
Panel= new JPanel( new GridBagLayout());
VorhersageLabel = new JLabel("Vorhersage:------");
GridBagConstraints c = new GridBagConstraints();
c.insets= new Insets(10,10,10,10);
c.gridx=0;
c.gridy=1;
Panel.add(TemperaturLabel,c);
c.gridx=1;
c.gridy=1;
Panel.add(Temperatur,c);
c.gridx=0;
c.gridy=2;
Panel.add(LuftfeuchtigkeitLabel,c);
c.gridx=1;
c.gridy=2;
Panel.add(Luftfeuchtigkeit,c);
c.gridx=0;
c.gridy=3;
Panel.add(luftdruckLabel,c);
c.gridx=1;
c.gridy=3;
Panel.add(luftdruck,c);
c.gridx=0;
c.gridy=4;
Panel.add(VorhersageLabel,c);
c.gridx=1;
c.gridy=4;
}
public Dimension getPreferredSize() {
return new Dimension(900,700);
}
}
So you're expecting to see something like this?
There were a number of logical errors in that code that caused a number of problems. Here is the corrected code with comments on most of them. (Some were not fixed as they did not make much difference in the end.)
The fundamental problem came from both extending and creating an instance of the JPanel. What ended up in the frame was the extended panel to which nothing had been added!
import java.awt.*;
import javax.swing.*;
// Use meaningful names for classes, attributes and methods!
// Don't. Extend. JFrame!
// public class Main extends JFrame {
public class MyPanelDisplayProblem {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// See comments below
// JPanel p = createAndShowGUI();
createAndShowGUI();
}
});
}
// why is this method returning anything? It makes no sense to do that.
// private static JPanel createAndShowGUI() {
private static void createAndShowGUI() {
System.out.println("Created GUI on EDT? "
+ SwingUtilities.isEventDispatchThread());
JFrame f = new JFrame("Swing Demo");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Oh my! This clashes with another name in my 'junk code' package!
// Again. Descriptive names!
// MyPanel p = new MyPanel();
WeatherPanel p = new WeatherPanel();
f.add(p.getPanel());
//f.add(new MyPanel());
f.pack();
f.setVisible(true);
}
}
/* Don't extend panels either, unless custom painting. */
//class WeatherPanel extends JPanel {
class WeatherPanel {
/*
* Please learn common Java nomenclature (naming conventions - e.g.
`EachWordUpperCaseClass`, `firstWordLowerCaseMethod()`,
`firstWordLowerCaseAttribute` unless it is an `UPPER_CASE_CONSTANT`)
and use it consistently.
*/
private JLabel TemperaturLabel ;
private JTextField Temperatur ;
private JLabel LuftfeuchtigkeitLabel;
private JTextField Luftfeuchtigkeit;
private JLabel luftdruckLabel;
private JTextField luftdruck;
private JLabel VorhersageLabel;
private JPanel Panel;
/*
The resoning here is entirely wrong. Components should be created and
added from within a constructor!
*/
// protected void paintComponent(Graphics g) {
public WeatherPanel() {
TemperaturLabel = new JLabel("Temperatur: ");
Temperatur = new JTextField(2);
LuftfeuchtigkeitLabel = new JLabel("Luftfeuchtigkeit: ");
Luftfeuchtigkeit = new JTextField(3);
luftdruckLabel = new JLabel("Luftdruck: ");
luftdruck = new JTextField(4);
Panel= new JPanel( new GridBagLayout());
VorhersageLabel = new JLabel("Vorhersage:------");
GridBagConstraints c = new GridBagConstraints();
c.insets= new Insets(10,10,10,10);
c.gridx=0;
c.gridy=1;
Panel.add(TemperaturLabel,c);
c.gridx=1;
c.gridy=1;
Panel.add(Temperatur,c);
c.gridx=0;
c.gridy=2;
Panel.add(LuftfeuchtigkeitLabel,c);
c.gridx=1;
c.gridy=2;
Panel.add(Luftfeuchtigkeit,c);
c.gridx=0;
c.gridy=3;
Panel.add(luftdruckLabel,c);
c.gridx=1;
c.gridy=3;
Panel.add(luftdruck,c);
c.gridx=0;
c.gridy=4;
Panel.add(VorhersageLabel,c);
c.gridx=1;
c.gridy=4;
}
// Now to get the panel that is created, we can add a 'get panel' method.
public JPanel getPanel() {
return Panel;
}
/**
* This is both unnecessary and counterproductive.
* See [Should I avoid the use of set(Preferred|Maximum|Minimum)Size
* methods in Java Swing?](http://stackoverflow.com/q/7229226/418556)
* (Yes.)
*/
/*
public Dimension getPreferredSize() {
return new Dimension(900,700);
}
*/
}
I took your code, rearranged it, and added a few things to get this GUI.
I redid your createAndShowGUI method to remove the static and use a new getPanel method I created.
I redid your TemperaturePanel class to create and show a JPanel. I organized your Swing components in column, row order so I could visually verify the Swing components. I added the missing JTextField. I created getter methods so you could actually get and set the values in the JTextFields.
I formatted the code and used proper camelCase variable names.
Here's the revised code. I made the TemperaturePanel an inner class so I could post this code as one block.
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class TemperatureGUI {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TemperatureGUI().createAndShowGUI();
}
});
}
private void createAndShowGUI() {
System.out.println("Created GUI on EDT? " +
SwingUtilities.isEventDispatchThread());
JFrame f = new JFrame("Swing Demo");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TemperaturePanel p = new TemperaturePanel();
f.add(p.getPanel());
// f.add(new MyPanel());
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
}
public class TemperaturePanel {
private JTextField temperatur;
private JTextField luftfeuchtigkeit;
private JTextField luftdruck;
private JTextField vorhersage;
private JPanel panel;
public TemperaturePanel() {
this.panel = createAndShowPanel();
}
private JPanel createAndShowPanel() {
JPanel panel = new JPanel(new GridBagLayout());
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.LINE_START;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 1.0;
c.insets = new Insets(10, 10, 10, 10);
c.gridx = 0;
c.gridy = 1;
JLabel temperaturLabel = new JLabel("Temperatur: ");
panel.add(temperaturLabel, c);
c.gridx = 1;
c.gridy = 1;
temperatur = new JTextField(10);
panel.add(temperatur, c);
c.gridx = 0;
c.gridy = 2;
JLabel luftfeuchtigkeitLabel = new JLabel("Luftfeuchtigkeit: ");
panel.add(luftfeuchtigkeitLabel, c);
c.gridx = 1;
c.gridy = 2;
luftfeuchtigkeit = new JTextField(10);
panel.add(luftfeuchtigkeit, c);
c.gridx = 0;
c.gridy = 3;
JLabel luftdruckLabel = new JLabel("Luftdruck: ");
panel.add(luftdruckLabel, c);
c.gridx = 1;
c.gridy = 3;
luftdruck = new JTextField(10);
panel.add(luftdruck, c);
c.gridx = 0;
c.gridy = 4;
JLabel vorhersageLabel = new JLabel("Vorhersage:------");
panel.add(vorhersageLabel, c);
c.gridx = 1;
c.gridy = 4;
vorhersage = new JTextField(10);
panel.add(vorhersage, c);
return panel;
}
public JTextField getTemperatur() {
return temperatur;
}
public JTextField getLuftfeuchtigkeit() {
return luftfeuchtigkeit;
}
public JTextField getLuftdruck() {
return luftdruck;
}
public JTextField getVorhersage() {
return vorhersage;
}
public JPanel getPanel() {
return panel;
}
}
}
I'm fairly new to java and I'm having a problem trying to put more than one button on a row,
at the moment I'm adding both buttons to the panel, but I don't know how to separate their x locations, i.e. they are both being added directly on to of each other.
Do I need to create a new layout or can I find a solution using what I have at the moment?
public class Question1 {
public static void main (String[] args){
MyFrame f = new MyFrame("Simple Submit Cancel Form");
f.init();
}
}
class MyFrame extends JFrame{
MyFrame(String title){
super(title);
}
private JPanel mainPanel;
private GridBagConstraints cText = new GridBagConstraints();
private GridBagConstraints cButton = new GridBagConstraints();
private GridBagLayout gbLayout = new GridBagLayout();
void init(){
mainPanel = new JPanel();
mainPanel.setLayout(gbLayout);
mainPanel.setBorder(BorderFactory.createEmptyBorder(10,20,10,20));
this.setContentPane(mainPanel);
cText.anchor = GridBagConstraints.WEST;
cText.weightx = 0.0;
cText.gridx = 0;
cText.gridy = 0;
JTextField tf = new JTextField(20);
gbLayout.setConstraints(tf,cText);
mainPanel.add(tf);
cButton.gridwidth = 4;
cButton.weightx = 0.0;
cButton.gridx = 0;
cButton.gridy = 1;
JButton b = new JButton("Submit");
gbLayout.setConstraints(b,cButton);
mainPanel.add(b);
b = new JButton("Cancel");
gbLayout.setConstraints(b,cButton);
mainPanel.add(b);
this.pack();
this.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE) ;
this.setVisible(true);
}
Just increment the gridx value:
JButton b = new JButton("Submit");
// gbLayout.setConstraints(b,cButton);
mainPanel.add(b, cButton);
b = new JButton("Cancel");
cButton.gridx++;
// gbLayout.setConstraints(b,cButton);
mainPanel.add(b, cButton);
Also you need to use the constraints created when adding your component to the grid bag layout using container.
e.g.,
import java.awt.*;
import javax.swing.*;
public class Question1 {
public static void main(String[] args) {
MyFrame f = new MyFrame("Simple Submit Cancel Form");
f.init();
}
}
class MyFrame extends JFrame {
private static final int GAP = 2;
MyFrame(String title) {
super(title);
}
private JPanel mainPanel;
private GridBagLayout gbLayout = new GridBagLayout();
void init() {
mainPanel = new JPanel();
mainPanel.setLayout(gbLayout);
mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20));
this.setContentPane(mainPanel);
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.WEST;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(GAP, GAP, GAP, GAP);
gbc.gridwidth = 2;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.gridx = 0;
gbc.gridy = 0;
JTextField tf = new JTextField(20);
mainPanel.add(tf, gbc);
gbc.gridwidth = 1;
gbc.gridx = 0;
gbc.gridy = 1;
JButton b = new JButton("Submit");
mainPanel.add(b, gbc);
b = new JButton("Cancel");
gbc.gridx++;
mainPanel.add(b, gbc);
this.pack();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
}
Try the following code:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Question1 {
public static void main(String[] args) {
MyFrame f = new MyFrame("Simple Submit Cancel Form");
f.init();
}
}
class MyFrame extends JFrame {
MyFrame(String title) {
super(title);
}
private JPanel mainPanel;
private GridBagConstraints cText = new GridBagConstraints();
private GridBagConstraints cButton = new GridBagConstraints();
private GridBagLayout gbLayout = new GridBagLayout();
void init() {
mainPanel = new JPanel();
mainPanel.setLayout(gbLayout);
mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20));
this.setContentPane(mainPanel);
cText.anchor = GridBagConstraints.WEST;
cText.weightx = 0.0;
cText.gridx = 0;
cText.gridy = 0;
JTextField tf = new JTextField(20);
gbLayout.setConstraints(tf, cText);
mainPanel.add(tf);
cButton.gridwidth = 4;
cButton.weightx = 0.0;
cButton.gridx = 0;
cButton.gridy = 1;
JPanel demoPanel = new JPanel();
JButton b = new JButton("Submit");
gbLayout.setConstraints(demoPanel, cButton);
demoPanel.add(b);
b = new JButton("Cancel");
// gbLayout.setConstraints(b,cButton);
demoPanel.add(b);
mainPanel.add(demoPanel);
this.pack();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
}
I have just put the two buttons inside a JPanel and put the JPanel inside the GridBagLayout Panel !
I have a problem while refreshing the content pane of my GUI. I can create a listener that is executed, but I can't manage to access the content pane to update it. Here is my code so far:
Egutegia() and Hasiera() and constructors for JPanels with different data. They load correctly when set to variable centralData from the beggining. My goal is to change between one another when clicking the buttons with their name. So far I only tried to implement one.
The action listener is written in the later part. It prints "reaches here" correctly. However, I dont know how to acces the content pane (content) from there and redraw the corresponding JPanel.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class MyApp{
private static String message1 = "message1";
private static String message2 = "message2";
private static BotMessage botMessage;
private static TopButtons topButtons;
private static JButton[] buttons;
private static JButton b1,b2,b3,b4;
public static JPanel centralData = new Hasiera();
private static class BotMessage extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
double h = getHeight();
double w = getWidth();
Font font = new Font("default", Font.BOLD, (int)(h/2));
g.setFont(font);
int stw = g.getFontMetrics().stringWidth(message2);
g.drawString(message1, (int)(w*0.02), (int)(3*h/4));
g.drawString(message2,(int) (w*0.98 - stw),(int)(3*h/4));
setBackground(Color.ORANGE);
}
public static class TopButtons extends JPanel{
public TopButtons(JButton buttons[]){
setLayout(new GridLayout(1,1));
setBackground(Color.ORANGE);
for (int i=0;i < buttons.length;i++){
add(buttons[i]);
}
}
}
/*
* LOADING EVERYTHING INTO A WINDOW
*/
public static void main(String[] args) {
botMessage = new BotMessage();
b1 = new JButton("Hasiera");
ActionListener ref = new ActionListener(){
public void actionPerformed(ActionEvent e){
centralData = new Egutegia();
System.out.println("reaches here");
}
};
b1.addActionListener(ref);
b2 = new JButton("Egutegia");
b3 = new JButton("Foroa");
b4 = new JButton("Txata");
buttons = new JButton[]{b1,b2,b3,b4};
topButtons = new TopButtons(buttons);
JPanel content = new JPanel();
content.setLayout(new GridBagLayout());
GridBagConstraints c1 = new GridBagConstraints();
c1.fill = GridBagConstraints.BOTH;
c1.weighty = 0.02;
c1.gridx = 0;
c1.gridy = 0;
c1.gridwidth = 2;
content.add(topButtons, c1);
GridBagConstraints c2 = new GridBagConstraints();
c2.weightx = 1;
c2.weighty = 1;
c2.fill = GridBagConstraints.BOTH;
c2.gridx = 0;
c2.gridy = 1;
content.add(centralData, c2);
GridBagConstraints c3 = new GridBagConstraints();
c3.fill = GridBagConstraints.BOTH;
c3.weighty = 0.04;
c3.gridx = 0;
c3.gridy = 2;
content.add(botMessage, c3);
JFrame window = new JFrame("MY APP");
window.setContentPane(content);
window.setSize(400,600);
window.setLocation(100,100);
window.setVisible(true);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
I am designing an application, in which there should be 5 different JPanels containing different Swing components. For the JRadioButton part, I ran into an issue for which couldn't find proper solution. The 'radioSizePanel' is supposed to be placed somewhere in upper middle of the main panel. Has anyone solved this problem before ? Here is the code, that I am using :
import java.awt.*;
import javax.swing.*;
public class PizzaShop extends JFrame
{
private static final long serialVersionUID = 1L;
private JRadioButton[] radio_size = new JRadioButton[3];
private JRadioButton[] radio_type = new JRadioButton[3];
public PizzaShop()
{
initializaUI();
}
private void initializaUI()
{
setSize(700, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Panel container to wrap checkboxes and radio buttons
JPanel panel = new JPanel();
//sizes radio buttons
String Size[] = {"Small: $6.50", "Medium: $8.50", "Large: $10.00"};
JPanel radioSizePanel = new JPanel(new GridLayout(3, 1));
ButtonGroup radioSizeGroup = new ButtonGroup();
for (int i=0; i<3; i++)
{
radio_size[i] = new JRadioButton(Size[i]);
radioSizePanel.add(radio_size[i]);
radioSizeGroup.add(radio_size[i]);
}
radioSizePanel.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Size"));
radioSizePanel.setPreferredSize(new Dimension(100, 200));
//
panel.add(radioSizePanel);
setContentPane(panel);
setContentPane(radioSizePanel);
}
public static void main(String[] args)
{
// TODO Auto-generated method stub
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new PizzaShop().setVisible(true);
}
});
}
}
Here is what I want as an expected OUTPUT :
Please do watch the code example and Please do watch everything carefully , the sequence of adding things to the JFrame. Since in your example you calling setSize() much before something has been added to the JFrame, hence first add components to the container, and then call it's pack()/setSize() methods, so that it can realize that in a good way.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PizzaLayout
{
/*
* Five JPanels we will be using.
*/
private JPanel headerPanel;
private JPanel footerPanel;
// This JPanel will contain the middle components.
private JPanel centerPanel;
private JPanel toppingPanel;
private JPanel sizePanel;
private JPanel typePanel;
private JPanel buttonPanel;
private String[] toppings = {
"Tomato",
"Green Pepper",
"Black Olives",
"Mushrooms",
"Extra Cheese",
"Pepproni",
"Sausage"
};
private JCheckBox[] toppingsCBox;
private String[] sizePizza = {
"Small $6.50",
"Medium $8.50",
"Large $10.00"
};
private JRadioButton[] sizePizzaRButton;
private String[] typePizza = {
"Thin Crust",
"Medium Crust",
"Pan"
};
private JRadioButton[] typePizzaRButton;
private JButton processButton;
private ButtonGroup bGroupType, bGroupSize;
private JTextArea orderTArea;
private StringBuilder sBuilderOrder;
private void displayGUI()
{
JFrame frame = new JFrame("Pizza Shop");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
/*
* This JPanel is the base of all the
* other components, and at the end
* we will set this as Content Pane
* for the JFrame.
*/
JPanel contentPane = new JPanel();
contentPane.setLayout(new BorderLayout(5, 5));
contentPane.setBorder(
BorderFactory.createEmptyBorder(10, 10, 10, 10));
/*
* TOP PART of the LAYOUT.
*/
headerPanel = new JPanel();
JLabel headerLabel = new JLabel(
"Welcome to Home Style Pizza Shop"
, JLabel.CENTER);
headerLabel.setForeground(Color.RED);
headerPanel.add(headerLabel);
/*
* CENTER PART of the LAYOUT.
*/
centerPanel = new JPanel();
centerPanel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridheight = 2;
gbc.weightx = 0.3;
gbc.weighty = 1.0;
/*
* Above Constraints are for this part.
*/
toppingPanel = new JPanel();
toppingPanel.setBorder(
BorderFactory.createTitledBorder(
BorderFactory.createLineBorder(Color.RED),
"Each Topping $1.50"));
JPanel checkBoxesPanel = new JPanel();
checkBoxesPanel.setBorder(
BorderFactory.createEmptyBorder(5, 5, 5, 5));
checkBoxesPanel.setLayout(new GridLayout(0, 1, 5, 5));
toppingsCBox = new JCheckBox[toppings.length];
for (int i = 0; i < toppings.length; i++)
{
toppingsCBox[i] = new JCheckBox(toppings[i]);
checkBoxesPanel.add(toppingsCBox[i]);
}
toppingPanel.add(checkBoxesPanel);
centerPanel.add(toppingPanel, gbc);
// Till this.
gbc.gridx = 1;
gbc.gridheight = 1;
gbc.weighty = 0.7;
/*
* Above Constraints are for this part.
*/
sizePanel = new JPanel();
sizePanel.setBorder(
BorderFactory.createTitledBorder(
BorderFactory.createLineBorder(Color.RED),
"Pizza Size"));
JPanel radioBoxesPanel = new JPanel();
radioBoxesPanel.setBorder(
BorderFactory.createEmptyBorder(5, 5, 5, 5));
radioBoxesPanel.setLayout(new GridLayout(0, 1, 10, 10));
sizePizzaRButton = new JRadioButton[sizePizza.length];
bGroupSize = new ButtonGroup();
for (int i = 0; i < sizePizza.length; i++)
{
sizePizzaRButton[i] = new JRadioButton(sizePizza[i]);
bGroupSize.add(sizePizzaRButton[i]);
radioBoxesPanel.add(sizePizzaRButton[i]);
}
sizePanel.add(radioBoxesPanel);
centerPanel.add(sizePanel, gbc);
// Till this.
gbc.gridx = 2;
gbc.weighty = 0.7;
/*
* Above Constraints are for this part.
*/
typePanel = new JPanel();
typePanel.setBorder(
BorderFactory.createTitledBorder(
BorderFactory.createLineBorder(Color.RED),
"Pizza Type"));
JPanel radioBoxesTypePanel = new JPanel();
radioBoxesTypePanel.setBorder(
BorderFactory.createEmptyBorder(5, 5, 5, 5));
radioBoxesTypePanel.setLayout(new GridLayout(0, 1, 10, 10));
typePizzaRButton = new JRadioButton[typePizza.length];
bGroupType = new ButtonGroup();
for (int i = 0; i < typePizza.length; i++)
{
typePizzaRButton[i] = new JRadioButton(typePizza[i]);
bGroupType.add(typePizzaRButton[i]);
radioBoxesTypePanel.add(typePizzaRButton[i]);
}
typePanel.add(radioBoxesTypePanel);
centerPanel.add(typePanel, gbc);
// Till this.
gbc.gridx = 1;
gbc.gridy = 1;
gbc.weighty = 0.3;
gbc.gridwidth = 2;
processButton = new JButton("Process Selection");
processButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent ae)
{
sBuilderOrder = new StringBuilder();
sBuilderOrder.append("Pizza type : ");
for (int i = 0; i < typePizza.length; i++)
{
if (typePizzaRButton[i].isSelected())
sBuilderOrder.append(typePizzaRButton[i].getText());
}
sBuilderOrder.append("\n");
sBuilderOrder.append("Pizza Size : ");
for (int i = 0; i < sizePizza.length; i++)
{
if (sizePizzaRButton[i].isSelected())
sBuilderOrder.append(sizePizzaRButton[i].getText());
}
sBuilderOrder.append("\n");
sBuilderOrder.append("Toppings : ");
/*
* I hope you can do this part yourself now :-)
*/
orderTArea.setText(sBuilderOrder.toString());
}
});
centerPanel.add(processButton, gbc);
footerPanel = new JPanel();
footerPanel.setLayout(new BorderLayout(5, 5));
footerPanel.setBorder(
BorderFactory.createTitledBorder("Your Order : "));
orderTArea = new JTextArea(10, 10);
footerPanel.add(orderTArea, BorderLayout.CENTER);
contentPane.add(headerPanel, BorderLayout.PAGE_START);
contentPane.add(centerPanel, BorderLayout.CENTER);
contentPane.add(footerPanel, BorderLayout.PAGE_END);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
new PizzaLayout().displayGUI();
}
});
}
}
Here is the output of the same :
Please have a look at the following code
WizardPanel.java
package wizardGUI;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class WizardPanel extends JDialog
{
private JPanel cardPanel, buttonPanel;
private JButton next,previous;
private CardLayout c1;
private FileSelector fileSelector;
private DelemeterSelector delemeterSelector;
private int count = 1;
public WizardPanel()
{
//Intializing instance variables
fileSelector = FileSelector.getInstance();
delemeterSelector = DelemeterSelector.getInstance();
cardPanel = new JPanel();
c1 = new CardLayout();
cardPanel.setLayout(c1);
cardPanel.add(fileSelector,"1");
cardPanel.add(delemeterSelector,"2");
c1.show(cardPanel, "1");;
buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
next = new JButton("Next");
next.addActionListener(new NextButtonAction());
previous = new JButton("Previous");
buttonPanel.add(next);
buttonPanel.add(previous);
//Creating the GUI
this.setLayout(new BorderLayout());
this.add(cardPanel,"Center");
this.add(buttonPanel,"South");
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.setResizable(true);
this.pack();
this.setVisible(true);
}
private class NextButtonAction implements ActionListener
{
public void actionPerformed(ActionEvent ae)
{
c1.show(cardPanel, "2");
}
}
}
FileSelector.java
package wizardGUI;
/*This is the first panel is wazard GUI. Using this window user can select the correct file
which contains the data required to create the table
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FileSelector extends JPanel
{
private JLabel fileName, description;
private JTextField fileTxt;
private JButton browse;
private GridBagLayout gbl;
private GridBagConstraints gbc;
private static FileSelector instance = null;
private FileSelector()
{
//Intializing instance variables
fileName = new JLabel("File Name: ");
description = new JLabel("Specify the source of the data");
fileTxt = new JTextField(10);
browse = new JButton("Browse");
gbl = new GridBagLayout();
gbc = new GridBagConstraints();
//Creating GUI
this.setLayout(gbl);
gbc.gridx = 1;
gbc.gridy = 1;
gbc.weightx = 0.0;
gbc.weighty = 0.0;
gbc.fill = GridBagConstraints.BOTH;
this.add(description,gbc);
gbc.gridx = 1;
gbc.gridy = 2;
gbc.weightx = 1.0;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = new Insets(0,10,0,0);
this.add(locationPanel(),gbc);
this.setBorder(BorderFactory.createEmptyBorder());
}
private JPanel locationPanel()
{
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
panel.add(fileName);
panel.add(fileTxt);
panel.add(browse);
return panel;
}
public static FileSelector getInstance()
{
if(instance==null)
{
instance = new FileSelector();
}
return instance;
}
}
DelemeterSelector.java
/*This is the second windows in wizard
This class is designed to let the user to select the delemeter to break information */
package wizardGUI;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class DelemeterSelector extends JPanel
{
private JLabel description;
private JRadioButton tabBtn, semicolanBtn, commaBtn, spaceBtn;
private JTextArea txtArea;
private JScrollPane scroll;
private ButtonGroup btnGroup;
private GridBagLayout gbl;
private GridBagConstraints gbc;
private static DelemeterSelector instance = null;
private DelemeterSelector()
{
//Initializing instance variables
description = new JLabel("What delemeter separates your fields? Select the appropreiate delemeter");
tabBtn = new JRadioButton("Tab");
semicolanBtn = new JRadioButton("Semicolan");
commaBtn = new JRadioButton("Comma");
spaceBtn = new JRadioButton("Space");
btnGroup = new ButtonGroup();
btnGroup.add(tabBtn);
btnGroup.add(semicolanBtn);
btnGroup.add(commaBtn);
btnGroup.add(spaceBtn);
txtArea = new JTextArea(20,70);
scroll = new JScrollPane(txtArea);
gbl = new GridBagLayout();
gbc = new GridBagConstraints();
this.setLayout(gbl);
//Creating the GUI
gbc.gridx = 1;
gbc.gridy = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = new Insets(20,0,0,0);
this.add(description,gbc);
gbc.gridx = 1;
gbc.gridy = 2;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = new Insets(20,0,0,0);
this.add(radioPanel(),gbc);
gbc.gridx = 1;
gbc.gridy = 3;
gbc.insets = new Insets(10,0,0,0);
gbc.fill = GridBagConstraints.BOTH;
this.add(scroll,gbc);
}
private JPanel radioPanel()
{
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
panel.add(tabBtn);
panel.add(semicolanBtn);
panel.add(commaBtn);
panel.add(spaceBtn);
panel.setBorder(BorderFactory.createTitledBorder("Choose the Delimeter that seperates your fields"));
return panel;
}
public static DelemeterSelector getInstance()
{
if(instance == null)
{
instance = new DelemeterSelector();
}
return instance;
}
}
Main.java
package wizardGUI
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class Main extends JFrame
{
public Main()
{
new WizardPanel().setVisible(true);
}
public static void main(String[]args)
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
new Main();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
In here, we have only two buttons "Next" and "Previous" and they are commong for all the JPanels because it appears in "South" of 'WizardPanel' while other JPanels are in center.
Now, lets take "FileSelector". Guess I selected a file using the browse button.
Now how can I send this information to the next panel? which means to "DelemeterSelector" ?. I have only 2 'COMMON' buttons "Next" and "previous" which are located in ANOTHER CLASS.
I don't think writing business logic (getting selected file from 'FileSelector' and sending it to 'DelemeterSelector') inside that "Next" or "Previous" button's actionListener is a good idea. Because, I have to access another class, get it data and send it to the next JPanel (next class). There will be more JPanels, so this will be really hard and failing for sure.
I thought of adding "Next" and "Previous" buttons to each and every JPanel rather than the common ones. But then the problem is moving from one panel to another, because the reference to CardLayout is missing.
Please help me to find a correct and efficient way pass data from one class to another class, in this wizard. Thanks.
PS:
I don't want to do condition checking in "Next" buttons action class and let it hold all the actions. For an example, see the following EXAMPLE CODE snippet
//NON TESTED, NON COMPILED EXAMPLE CODE.
private class NextButtonAction implements ActionListener
{
public void actionPerformed(ActionEvent ae)
{
if(fileSelector.isVisible(true))
{
//Access FileSelector
// Get the Data
// send data into delemeter class
}
else if(delemeterSelector.isVisible(true))
{
//Access delemeterSelector
// Get the Data
// send data into other class
}
else if(SOME_OTHER_CLASS.isVisible(true))
{
//Access delemeterSelector
// Get the Data
// send data into other class
}
}
}
Lunch break is over, so all I have time for is to post sample code, but I'll try to come back to explain it before the end of the day:
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
import javax.swing.event.SwingPropertyChangeSupport;
public class MainGui {
public MainGui() {
new WizardPanel().setVisible(true);
}
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
new MainGui();
} catch (Exception e) {
e.printStackTrace();
}
}
}
class WizardPanel extends JDialog {
private JPanel cardPanel, buttonPanel;
private JButton next, previous;
private CardLayout c1;
private SimpleModel simpleModel = new SimpleModel();
private FileSelector fileSelector;
private DelemeterSelector delemeterSelector;
private int count = 1;
public WizardPanel() {
fileSelector = FileSelector.getInstance();
delemeterSelector = DelemeterSelector.getInstance();
fileSelector.setModel(simpleModel); //!!
delemeterSelector.setModel(simpleModel); //!!
cardPanel = new JPanel();
c1 = new CardLayout();
cardPanel.setLayout(c1);
cardPanel.add(fileSelector, "1");
cardPanel.add(delemeterSelector, "2");
c1.show(cardPanel, "1");
buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
next = new JButton("Next");
next.addActionListener(new NextButtonAction());
previous = new JButton("Previous");
buttonPanel.add(next);
buttonPanel.add(previous);
// Creating the GUI
this.setLayout(new BorderLayout());
this.add(cardPanel, "Center");
this.add(buttonPanel, "South");
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.setResizable(true);
this.pack();
this.setVisible(true);
}
private class NextButtonAction implements ActionListener {
public void actionPerformed(ActionEvent ae) {
// c1.show(cardPanel, "2");
c1.next(cardPanel); //!!
}
}
}
class FileSelector extends JPanel {
private JLabel fileName, description;
private JTextField fileTxt;
private JButton browse;
private GridBagLayout gbl;
private GridBagConstraints gbc;
private SimpleModel simpleModel;
private static FileSelector instance = null;
private FileSelector() {
// Intializing instance variables
fileName = new JLabel("File Name: ");
description = new JLabel("Specify the source of the data");
fileTxt = new JTextField(10);
browse = new JButton("Browse");
browse.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (simpleModel != null) {
simpleModel.setFileText(fileTxt.getText());
}
}
});
gbl = new GridBagLayout();
gbc = new GridBagConstraints();
// Creating GUI
this.setLayout(gbl);
gbc.gridx = 1;
gbc.gridy = 1;
gbc.weightx = 0.0;
gbc.weighty = 0.0;
gbc.fill = GridBagConstraints.BOTH;
this.add(description, gbc);
gbc.gridx = 1;
gbc.gridy = 2;
gbc.weightx = 1.0;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = new Insets(0, 10, 0, 0);
this.add(locationPanel(), gbc);
this.setBorder(BorderFactory.createEmptyBorder());
}
public void setModel(SimpleModel simpleModel) {
this.simpleModel = simpleModel;
}
private JPanel locationPanel() {
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
panel.add(fileName);
panel.add(fileTxt);
panel.add(browse);
return panel;
}
public static FileSelector getInstance() {
if (instance == null) {
instance = new FileSelector();
}
return instance;
}
}
class DelemeterSelector extends JPanel {
private JLabel description;
private JRadioButton tabBtn, semicolanBtn, commaBtn, spaceBtn;
private JTextArea txtArea;
private JScrollPane scroll;
private ButtonGroup btnGroup;
private GridBagLayout gbl;
private GridBagConstraints gbc;
private SimpleModel simpleModel;
private static DelemeterSelector instance = null;
private DelemeterSelector() {
description = new JLabel(
"What delemeter separates your fields? Select the appropreiate delemeter");
tabBtn = new JRadioButton("Tab");
semicolanBtn = new JRadioButton("Semicolan");
commaBtn = new JRadioButton("Comma");
spaceBtn = new JRadioButton("Space");
btnGroup = new ButtonGroup();
btnGroup.add(tabBtn);
btnGroup.add(semicolanBtn);
btnGroup.add(commaBtn);
btnGroup.add(spaceBtn);
txtArea = new JTextArea(20, 70);
scroll = new JScrollPane(txtArea);
gbl = new GridBagLayout();
gbc = new GridBagConstraints();
this.setLayout(gbl);
// Creating the GUI
gbc.gridx = 1;
gbc.gridy = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = new Insets(20, 0, 0, 0);
this.add(description, gbc);
gbc.gridx = 1;
gbc.gridy = 2;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = new Insets(20, 0, 0, 0);
this.add(radioPanel(), gbc);
gbc.gridx = 1;
gbc.gridy = 3;
gbc.insets = new Insets(10, 0, 0, 0);
gbc.fill = GridBagConstraints.BOTH;
this.add(scroll, gbc);
}
private JPanel radioPanel() {
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
panel.add(tabBtn);
panel.add(semicolanBtn);
panel.add(commaBtn);
panel.add(spaceBtn);
panel.setBorder(BorderFactory
.createTitledBorder("Choose the Delimeter that seperates your fields"));
return panel;
}
//!!
public void setModel(final SimpleModel simpleModel) {
this.simpleModel = simpleModel;
simpleModel.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if (SimpleModel.FILE_TEXT.equals(evt.getPropertyName())) {
txtArea.append("File Text: " + simpleModel.getFileText() + "\n");
}
}
});
}
public static DelemeterSelector getInstance() {
if (instance == null) {
instance = new DelemeterSelector();
}
return instance;
}
}
class SimpleModel {
public static final String FILE_TEXT = "file text";
private SwingPropertyChangeSupport pcSupport =
new SwingPropertyChangeSupport(this);
private String fileText;
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(listener);
}
public void setFileText(String fileText) {
String oldValue = this.fileText;
String newValue = fileText;
this.fileText = fileText;
pcSupport.firePropertyChange(FILE_TEXT, oldValue , newValue);
}
public String getFileText() {
return fileText;
}
}
Edit explanation of code:
This is a gross simplification of the Model-View-Controller or MVC design pattern since it is nothing more than model and view. The model holds the data and logic that the GUI works with and is essentially the "brains" of the program while the GUI is little more than a dumb display of the information.
The model here is quite simple and only holds one String field called fileText. It has setters and getters for this field, and the most interesting thing about it is the setter is wired so that it will notify any listeners that want to know if this field is ever changed. This process of using PropertyChangeSupport and allowing for PropertyChangeListeners means the the fileText field is a "bound" property.
Both of your JPanels have fields to hold a reference to the same SimpleModel object, and this model is set via a setter method, setModel(...).
fileSelector.setModel(simpleModel); // !!
delemeterSelector.setModel(simpleModel); // !!
I let the FileSelector object set the fileText field if its JButton is pressed:
browse.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (simpleModel != null) {
simpleModel.setFileText(fileTxt.getText());
}
}
});
I have the DelemeterSelector class add a PropertyChangeListener to the model so that it is notified whenever the fileText field's value is changed, and can respond to it as it sees fit:
public void setModel(final SimpleModel simpleModel) {
this.simpleModel = simpleModel;
simpleModel.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if (SimpleModel.FILE_TEXT.equals(evt.getPropertyName())) {
txtArea.append("File Text: " + simpleModel.getFileText() + "\n");
}
}
});
}
Note that the model class has no idea what the GUI does with the information it holds, and that's a good thing as it means that "coupling" is fairly loose.