I want to return values set in the first JPanel and use them to repaint the second JPanel by clicking the RYSUJ button. I need a simple solution to send the parameters:
My main class:
public static void main(String[] args) throws IOException {
FractalFrame gui = new FractalFrame();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gui.setVisible(true);
}
The frame:
public class FractalFrame extends JFrame {
public FractalFrame() {
setTitle("Fractalz beta");
setSize(800, 600);
setResizable(false);
FractalzGUI gui = new FractalzGUI();
FractalJPanel panel = new FractalJPanel(gui.kol, gui.zoom, gui.radio);
this.add(panel);
this.add(gui, BorderLayout.EAST);
}
}
The gui class (it's first JPanel):
public class FractalzGUI extends JPanel implements ActionListener {
private JRadioButton mandelbrotRadio = new JRadioButton("Zbiór Mandelbrota");
private JRadioButton shipRadio = new JRadioButton("Płonący statek");
private JLabel ustawZoom = new JLabel("zoom: ");
private JTextField zoomtf = new JTextField("", 5);
private JLabel wyborKoloru = new JLabel("Wybierz kolor: ");
private String[] kolory = {"zolty", "niebieski", "czerwony", "zielony", "brazowy", "fioletowy"};
private JComboBox listaKolorow = new JComboBox(kolory);
private JButton rysuj = new JButton("Rysuj!");
public int radio=0; //1 = mandelbrot, 2 = ship
public int zoom=0;
public int kol=0;
public FractalzGUI() {
this.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(0, 0, 0, 0);
gbc.gridx = 0;
gbc.gridy = 0;
this.add(mandelbrotRadio, gbc);
gbc.gridy = 1;
this.add(shipRadio, gbc);
gbc.gridx = 0;
gbc.gridy = 2;
this.add(ustawZoom, gbc);
gbc.gridx = 1;
this.add(zoomtf, gbc);
gbc.gridx = 0;
gbc.gridy = 3;
this.add(wyborKoloru, gbc);
gbc.gridx = 1;
this.add(listaKolorow, gbc);
gbc.gridx = 0;
gbc.gridy = 4;
this.add(rysuj, gbc);
mandelbrotRadio.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
shipRadio.setSelected(false);
}
});
shipRadio.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
mandelbrotRadio.setSelected(false);
}
});
rysuj.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (mandelbrotRadio.isSelected()) {
radio = 1;
} else if (shipRadio.isSelected()) {
radio = 2;
}
if(zoomtf.getText().equals("")) zoom=0;
else zoom=Integer.parseInt(zoomtf.getText());
switch(listaKolorow.getSelectedIndex()){
case 0:
kol = 40;
break;
case 1:
kol = 165;
break;
case 2:
kol = 256;
break;
case 3:
kol = 105;
break;
case 4:
kol = 20;
break;
case 5:
kol = 200;
break;
}
}
});
}
#Override
public void actionPerformed(ActionEvent e) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
Forget Swing, forget GUI's. The easiest way for one object to change the state of another is for the first object to call a method of the 2nd, passing information into it. You should have one class hold an instance of the other, and then have the first one call methods on the 2nd passing information in as needed. This can all be set up in your FractalFrame constructor, by passing in an instance of one class into the other.
You can even pass both in to each other if needed, but this will tighten coupling quite a bit.
i.e.,
FractalzGUI gui = new FractalzGUI();
FractalJPanel panel = new FractalJPanel(gui.kol, gui.zoom, gui.radio);
// obviously these classes need setter methods
gui.setFractalJPanel(panel);
this.add(panel);
this.add(gui, BorderLayout.EAST);
Edit
Called out by a professional and a purist ...
Better still, use a separate non-GUI model class that holds the logic that underlies your GUI. Allow the view classes (the GUI classes) to register listeners on the model, and then when one class changes the model, all listeners are notified and can query the model as to its state, and then adjust their views accordingly.
Related
I am currently working on GUI of simple food ordering system. I created a button that whenever user clicks it it will go to another frame, however I am facing problem when I want to close the first frame (setVisible(false)).
This is my first frame
public class MainFrame extends JFrame {
private Manager manager = new Manager();
private JPanel titlepane;
private JLabel title;
MainFrame(String name){
setTitle(name);
}
public void content() {
Font titlefont = new Font("Times New Roman", Font.PLAIN, 22);
setLayout(new BorderLayout());
titlepane = new JPanel();
title = new JLabel("Welcome to POS!");
title.setFont(titlefont);
titlepane.add(title);
manager.LoginGUI();
add(titlepane,BorderLayout.NORTH);
add(manager,BorderLayout.CENTER);
}
public void runGUI() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
content();
setSize(700,700);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setLocationRelativeTo(null);
}
});
}
This is another class where the button is
public class Manager extends JPanel implements ActionListener {
private ArrayList<AccountInfo> manager = new ArrayList<AccountInfo>();
private GridBagConstraints gbc = new GridBagConstraints();
private JLabel id;
private JLabel pw;
private JTextField idfill;
private JTextField pwfill;
private JButton login;
private int isManager = 0;
private String idinput, pwinput;
private int temp = -1;
Manager() {
this.manager.add(new AccountInfo("admin", "1234"));
}
public void addManager(AccountInfo newManager) {
this.manager.add(newManager);
}
public void LoginGUI() {
Font standard = new Font("Times New Roman", Font.PLAIN, 18);
setLayout(new GridBagLayout());
id = new JLabel("ID");
id.setFont(standard);
// Alignment
gbc.gridx = 0;
gbc.gridy = 0;
gbc.ipadx = 10;
gbc.ipady = 10;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.fill = GridBagConstraints.VERTICAL;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
add(id, gbc);
idfill = new JTextField(10);
idfill.setFont(standard);
// Alignment
gbc.gridx = 1;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
add(idfill, gbc);
pw = new JLabel("Password");
pw.setFont(standard);
// Alignment
gbc.gridx = 0;
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
add(pw, gbc);
pwfill = new JTextField(10);
pwfill.setFont(standard);
// Alignment
gbc.gridx = 1;
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
add(pwfill, gbc);
login = new JButton("Login");
login.setFont(standard);
login.addActionListener(this);
// Alignment
gbc.gridx = 1;
gbc.gridy = 2;
gbc.insets = new Insets(5, 5, 5, 5);
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
add(login, gbc);
}
public void actionPerformed(ActionEvent e) {
verify();
if(isManager == 1) {
MenuFrame menu = new MenuFrame("Menu");
menu.runGUI();
MainFrame.setVisible(false); // This is the problem
}
}
private void verify() {
idinput = idfill.getText().trim();
pwinput = pwfill.getText();
for (int i = 0; i < manager.size(); i++) {
if (idinput.equals(manager.get(i).id)) {
temp = i;
}
}
if(temp == -1) {
JOptionPane.showMessageDialog(null, "Id or password incorrect, try again");
} else if(pwinput.equals(manager.get(temp).password)) {
isManager = 1;
} else
JOptionPane.showMessageDialog(null, "Id or password incorrect, try again");
}
}
(The codes are a bit lengthy as I am not confident that the other part was correct. All I know this has nothing to do with MenuFrame)
I get this error:
Cannot make a static reference to the non-static method setVisible(boolean) from the type Window
It might be my fault where it is not obvious enough for me to know which part of Manager or MainFrame is static. I also came across other posts regarding the same issue but none relates with mine. (Other post was having obvious static method)
Also tried the create an MainFrame object in Manager but it made it worse, please help, thank you!
You indeed need to keep the MainFrame object somewhere accessible, keep a reference to it. For this MVC, Model-View-Controller, is a nice paradigm.
Use MVC
I personally have my main method for swing in a Controller class (so the controller is the application class). It creates the main frame (View) and the controller is passed.
public void actionPerformed(ActionEvent e) {
verify();
if(isManager == 1) {
MenuFrame menu = new MenuFrame("Menu");
menu.runGUI();
controller.setMainFrameVisible(false);
}
}
Controller:
private MainFrame mainFrame;
public setMainFrameVisible(boolean visible) {
MainFrame.setVisible(visible);
}
Pass the MainFrame instance.
However you may also pass the MainFrame:
private final MainFrame mainFrame;
Manager(MainFrame mainFrame) {
this.mainFrame = mainFrame;
}
public void actionPerformed(ActionEvent e) {
verify();
if(isManager == 1) {
MenuFrame menu = new MenuFrame("Menu");
menu.runGUI();
mainFrame.setVisible(false);
}
}
If the panel is inside the MainFrame
((JFrame) getTopLevelAncestor()).setVisible(false);
Tip:
Should the application exit (EXIT_ON_CLOSE), change the default close operation.
MainFrame(String name){
setTitle(name);
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
}
I was testing something with JPanel. When I added random text to the JTextArea inside it, it kept increasing the size of the JPanel until it reached the edge.
How do I keep the text inside the JPanel without stretching it?
public class Game
{
TitleScreenHandler tsHandler = new TitleScreenHandler();
ChoiceHandler choiceHandler = new ChoiceHandler();
ComponentHandler compHandler = new ComponentHandler();
GridBagConstraints gbc = new GridBagConstraints();
Border whiteline = BorderFactory.createLineBorder(Color.WHITE);
JFrame window;
Container con;
JPanel titlePanel , startPanel, mainTextPanel, choiceButtonPanel, playerPanel;
JLabel titleLabel, hpLabel, hpLabelNumber, weaponLabel, weaponLabelName;
public static JButton startButton, choice1,choice2,choice3,choice4,choice5,choice6,choice7,choice8;
public static JTextArea mainTextArea;
Font titleFont = new Font("Times New Roman", Font.PLAIN, 100);
Font normalFont = new Font("Times New Roman", Font.PLAIN, 30);
public static String playerName;
public static String weapon,position;
public static int playerHP;
public static int weaponDamage;
public static void main(String[] args)
{
new Game();
}
public Game()
{
window = new JFrame();
window.setSize(1440,900);
window.setTitle("W: " + window.getWidth() + " H: " + window.getHeight());
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.getContentPane().setBackground(Color.black);
window.setLayout(new GridBagLayout());
con = window.getContentPane();
//Panels are used to make sections in the window (Background)
//Labels are used to write in the sections/panels (Foreground)
//Buttons can be pressed inside Panels
//To make a text you need to design a panel, design its size/color,
//Design its text the same way, then add it to the panel
titlePanel = new JPanel();
titlePanel.setBounds(100, 100, 1080 , 150);
titlePanel.setBackground(Color.black);
titleLabel = new JLabel("Adventure");
titleLabel.setForeground(Color.white);
titleLabel.setFont(titleFont);
startPanel = new JPanel();
startPanel.setBounds(540, 600, 200, 100);
startPanel.setBackground(Color.black);
startButton = new JButton("START");
startButton.setBackground(Color.black);
startButton.setForeground(Color.white);
startButton.setFont(normalFont);
startButton.addActionListener(tsHandler);
window.addComponentListener(compHandler);
titlePanel.add(titleLabel);
startPanel.add(startButton);
con.add(titlePanel, gbc);
gbc.gridx = 0;
gbc.gridy = 2;
con.add(startPanel, gbc);
window.setVisible(true);
}
public void createGameScreen()
{
titlePanel.setVisible(false);
startButton.setVisible(false);
mainTextPanel = new JPanel();
//mainTextPanel.setBounds(100, 100, 1080, 250);
mainTextPanel.setBackground(Color.black);
mainTextPanel.setBorder(whiteline);
mainTextArea = new JTextArea("This is the main text area");
mainTextArea.setBounds(100,100,1080,250);
mainTextArea.setBackground(Color.black);
mainTextArea.setForeground(Color.white);
mainTextArea.setLayout(new GridLayout());
mainTextArea.setFont(normalFont);
mainTextArea.setLineWrap(true);
mainTextArea.setWrapStyleWord(true);
playerPanel = new JPanel();
playerPanel.setBounds(100, 100, 1080, 50);
playerPanel.setBackground(Color.blue);
playerPanel.setLayout(new GridLayout(1,4));
choiceButtonPanel = new JPanel();
choiceButtonPanel.setBounds(500, 350, 300, 250);
choiceButtonPanel.setLayout(new GridLayout(2,4, 50, 50));
choiceButtonPanel.setBackground(Color.red);
choice1 = new JButton("Choice 1");
choice1.setBackground(Color.black);
choice1.setForeground(Color.white);
choice1.setFont(normalFont);
choice1.setFocusPainted(false);
choice1.addActionListener(choiceHandler);
choice1.setActionCommand("c1");
choiceButtonPanel.add(choice1);
choice2 = new JButton("Choice 2");
choice2.setBackground(Color.black);
choice2.setForeground(Color.white);
choice2.setFont(normalFont);
choice2.setFocusPainted(false);
choice2.addActionListener(choiceHandler);
choice2.setActionCommand("c2");
choiceButtonPanel.add(choice2);
choice3 = new JButton("Choice 3");
choice3.setBackground(Color.black);
choice3.setForeground(Color.white);
choice3.setFont(normalFont);
choice3.setFocusPainted(false);
choice3.addActionListener(choiceHandler);
choice3.setActionCommand("c3");
choiceButtonPanel.add(choice3);
choice4 = new JButton("Choice 4");
choice4.setBackground(Color.black);
choice4.setForeground(Color.white);
choice4.setFont(normalFont);
choice4.setFocusPainted(false);
choice4.addActionListener(choiceHandler);
choice4.setActionCommand("c4");
choiceButtonPanel.add(choice4);
choice5 = new JButton("Choice 5");
choice5.setBackground(Color.black);
choice5.setForeground(Color.white);
choice5.setFont(normalFont);
choice5.setFocusPainted(false);
choice5.addActionListener(choiceHandler);
choice5.setActionCommand("c5");
choiceButtonPanel.add(choice5);
choice6 = new JButton("Choice 6");
choice6.setBackground(Color.black);
choice6.setForeground(Color.white);
choice6.setFont(normalFont);
choice6.setFocusPainted(false);
choice6.addActionListener(choiceHandler);
choice6.setActionCommand("c6");
choiceButtonPanel.add(choice6);
choice7 = new JButton("Choice 7");
choice7.setBackground(Color.black);
choice7.setForeground(Color.white);
choice7.setFont(normalFont);
choice7.setFocusPainted(false);
choice7.addActionListener(choiceHandler);
choice7.setActionCommand("c7");
choiceButtonPanel.add(choice7);
choice8 = new JButton("Choice 8");
choice8.setBackground(Color.black);
choice8.setForeground(Color.white);
choice8.setFont(normalFont);
choice8.setFocusPainted(false);
choice8.addActionListener(choiceHandler);
choice8.setActionCommand("c8");
choiceButtonPanel.add(choice8);
gbc.anchor = GridBagConstraints.PAGE_END;
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 0;
con.add(playerPanel,gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
//gbc.ipadx = 750;
gbc.ipady = 1000;
gbc.gridwidth = 2;
gbc.gridx = 1;
gbc.gridy = 0;
con.add(mainTextPanel,gbc);
gbc.fill = GridBagConstraints.NONE;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.gridx = 1;
gbc.gridy = 5;
con.add(choiceButtonPanel,gbc);
hpLabel = new JLabel("HP: ");
hpLabel.setFont(normalFont);
hpLabel.setForeground(Color.white);
hpLabelNumber = new JLabel();
hpLabelNumber.setFont(normalFont);
hpLabelNumber.setForeground(Color.white);
weaponLabel = new JLabel("Weapon: ");
weaponLabel.setFont(normalFont);
weaponLabel.setForeground(Color.white);
weaponLabelName = new JLabel();
weaponLabelName.setFont(normalFont);
weaponLabelName.setForeground(Color.white);
playerPanel.add(hpLabel);
playerPanel.add(hpLabelNumber);
playerPanel.add(weaponLabel);
playerPanel.add(weaponLabelName);
mainTextPanel.add(mainTextArea, BorderLayout.PAGE_START);
playerSetup();
}
public void playerSetup()
{
playerHP = 15;
weapon = "Fists";
weaponLabelName.setText(weapon);
hpLabelNumber.setText("" + playerHP);
ForestEvents.townGate();
}
/*public void townGate()
{
position = "towngate";
mainTextArea.setText("You are at the gates of the town. A guard is standing in front of you. What do you do?");
choice1.setText("Talk to the Guard");
choice2.setText("Attack the Guard");
choice3.setText("Leave");
choice4.setText("");
}*/
public void talkGuard()
{
position = "talkguard";
mainTextArea.setText("Guard: Hello Stranger. I have never seen you before. I'm sorry but I cannot let you enter.");
choice1.setText("Go Back");
choice2.setText("");
choice3.setText("");
choice4.setText("");
}
public void attackGuard()
{
position = "attackguard";
mainTextArea.setText("Guard: HOW DARE YOU!\nThe guard fought back and hit you hard.\n(You received 3 damage)");
playerHP -= 3;
hpLabelNumber.setText("" + playerHP);
choice1.setText("Go Back");
choice2.setText("");
choice3.setText("");
choice4.setText("");
}
public void crossRoad()
{
position = "crossroads";
mainTextArea.setText("You are at the crossroad.\n Go south to go back to the town.");
choice1.setText("Go North");
choice2.setText("Go East");
choice3.setText("Go South");
choice4.setText("Go West");
}
public class ComponentHandler implements ComponentListener
{
public void componentResized(ComponentEvent e)
{
Component c = (Component)e.getSource();
window.setTitle("W: " + c.getWidth() + " H: " + c.getHeight());
}
#Override
public void componentHidden(ComponentEvent e)
{
// TODO Auto-generated method stub
}
#Override
public void componentMoved(ComponentEvent e)
{
}
#Override
public void componentShown(ComponentEvent e)
{
}
}
public class TitleScreenHandler implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
createGameScreen();
}
}
public class ChoiceHandler implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
String yourChoice = event.getActionCommand();
switch (position)
{
case "towngate":
switch(yourChoice)
{
case "c1":
talkGuard();
break;
case "c2":
attackGuard();
break;
case "c3":
crossRoad();
break;
case "c4":
break;
}
break;
case "talkguard":
switch(yourChoice)
{
case "c1":
ForestEvents.townGate();
break;
}
break;
case "attackguard":
switch(yourChoice)
{
case "c1":
ForestEvents.townGate();
break;
}
break;
case "crossroad":
switch(yourChoice)
{
case"c1":
break;
case"c2":
break;
case"c3":
ForestEvents.townGate();
break;
case"c4":
break;
}
break;
}
}
}
}
Edit: Added the rest of the code and added the textarea to the scrollpane and the scrollpane to the Jpanel now the text isnt showing up in the panel.
import javax.swing.JTextArea;
public class ForestEvents
{
String pos;
int hp;
public ForestEvents()
{
pos = Game.position;
hp = Game.playerHP;
}
public static void townGate()
{
Game.position = "towngate";
Game.mainTextArea.setText("You are at the gates of the town. A guard is standing in front of you. What do you do? \na\nas\n\n\n\n\\n"
+ "\n\n\n\1\n1\n\n\n\n\n\\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n1\n1\n2\n2\n3\n4\n6");
Game.choice1.setText("Talk to the Guard");
Game.choice2.setText("Attack the Guard");
Game.choice3.setText("Leave");
Game.choice4.setText("");
}
}
You will want to get your JTextArea into JScrollPane, as Adeel said in the comments (+1), then control it with GridBagLayout. No need to set component bounds, preferred size etc. If you want to use GridBagLayout, you have to learn how weights work with fill and anchor. In code below change gbc.fill HORIZONTAL to VERTICAL and swap weights I used for adding scroll to window (so it should be weightx=0,y=1), or change fill to BOTH and make both weights equal to 1 (in this case, you can comment out this empty JLabel I added at the end). Observe and learn.
In your code, you're not setting weights. So, as you may have guessed, everything has the same weight. mainTextArea is added while gbc.fill is HORIZONTAL, no weights and is not inside JScrollPane - that's why it stretches. And be careful with ipads.
SSCCE (comments in code)
public class DontStretchMyTextArea {
public static void main(String[] args) {
JFrame window = new JFrame();
window.setSize(1440, 900);
window.setTitle("W: " + window.getWidth() + " H: " + window.getHeight());
window.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
window.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.anchor = GridBagConstraints.NORTH;
gbc.insets = new Insets(10, 10, 10, 10);
JTextArea mainTextArea = new JTextArea( "This is the main text area" , 10 , 30 ); //here you can set how many rows/columns you want,
//but anyway GridBagLayout will recalculate size of component
//based on gbc.fill, weights and surrounding components
//mainTextArea.setLayout(new GridLayout());
mainTextArea.setLineWrap(true);
mainTextArea.setWrapStyleWord(true);
JScrollPane scroll = new JScrollPane(mainTextArea);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
GridBagConstraints panelGBC = new GridBagConstraints();
panelGBC.weightx = 1; //I want to fill whole panel with JTextArea
panelGBC.weighty = 1; //so both weights =1
panelGBC.fill = GridBagConstraints.BOTH; //and fill is set to BOTH
panel.add(scroll, panelGBC);
panel.setBackground(Color.gray);//this shouldn't be visible
gbc.weightx = 1;
gbc.weighty = 0;
window.add(panel, gbc);
gbc.weightx = 1;
gbc.weighty = 1;
gbc.gridx++;
window.add(new JLabel(), gbc); //GridBagLayout always needs component with both weights =1
SwingUtilities.invokeLater(() -> { //we get our frame on EDT
window.pack();
window.setVisible(true);
});
}
}
How to use GridBagLayout
You can also add scroll directly to window. panel was created just for illustration purposes.
I'm very new to java I have been doing basic stuff and for my final project we wanted to create a gui rpg. Our problem right now is we can't figure out how to open another program by clicking the gui button. My friends told me you guys use eclipse so I don't have to show imports. Keep in mind I'm in highschool so don't judge too harsh :D Here is our code:
public class Narnia {
private static final String BACKHGROUND_IMAGE_URL = "http://randomwallpapers.net/fantasy-castle-1920x1080-wallpaper328374.jpg";
protected void initUI() throws MalformedURLException {
JFrame frame = new JFrame(Narnia.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final ImageIcon backgroundImage = new ImageIcon(new URL(BACKHGROUND_IMAGE_URL));
JLabel mainPanel = new JLabel(backgroundImage) {
#Override
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
Dimension lmPrefSize = getLayout().preferredLayoutSize(this);
size.width = Math.max(size.width, lmPrefSize.width);
size.height = Math.max(size.height, lmPrefSize.height);
return size;
}
};
mainPanel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(10, 10, 10, 10);
gbc.weightx = 1.0;
gbc.anchor = GridBagConstraints.WEST;
gbc.gridwidth = GridBagConstraints.REMAINDER;
for (int i = 0; i < 1; i++) {
mainPanel.add(new JButton("Play" + ("")), gbc);
}
for (int i = 0; i < 1; i++) {
mainPanel.add(new JButton("Credits " + ("")), gbc);
}
for (int i = 0; i < 1; i++) {
mainPanel.add(new JButton("Exit " + ("")), gbc);
}
// Let's put a filler bottom component that will push the rest to the top
gbc.weighty = 1.0;
mainPanel.add(Box.createGlue(), gbc);
frame.add(mainPanel);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
new Narnia().initUI();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
Here is the class we want to open:
public class chooseaclass {
private static final String BACKHGROUND_IMAGE_URL = "http://randomwallpapers.net/fantasy-castle-1920x1080-wallpaper328374.jpg";
protected void initUI() throws MalformedURLException {
JFrame frame = new JFrame(chooseaclass.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final ImageIcon backgroundImage = new ImageIcon(new URL(BACKHGROUND_IMAGE_URL));
JLabel mainPanel = new JLabel(backgroundImage) {
#Override
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
Dimension lmPrefSize = getLayout().preferredLayoutSize(this);
size.width = Math.max(size.width, lmPrefSize.width);
size.height = Math.max(size.height, lmPrefSize.height);
return size;
}
};
mainPanel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(40, 40, 40, 40);
gbc.weightx = 1.0;
gbc.anchor = GridBagConstraints.CENTER;
gbc.gridwidth = GridBagConstraints.REMAINDER;
for (int i = 0; i < 1; i++) {
mainPanel.add(new JButton("Archer" + ("")), gbc);
}
for (int i = 0; i < 1; i++) {
mainPanel.add(new JButton("Mage " + ("")), gbc);
}
for (int i = 0; i < 1; i++) {
mainPanel.add(new JButton("Knight " + ("")), gbc);
}
// Let's put a filler bottom component that will push the rest to the top
gbc.weighty = 1.0;
mainPanel.add(Box.createGlue(), gbc);
frame.add(mainPanel);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
new chooseaclass().initUI();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
You need to add a listener to whatever button you want. In this case, we'll use an ActionListener.
Let's just use this existing line that you already have: mainPanel.add(new JButton("Play" + ("")), gbc);
First of all, to make it simpler, let's put that JButton in a variable:
JButton playButton = new JButton("Play" + (""));
To add a listener, we need to use the method addActionListener().
Now add an ActionListener as an anonymous class so that we can implement a method that the system can call behind the scenes:
JButton playButton = new JButton("Play" + (""));
playButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
new chooseaclass.initUI() //insantiate a new chooseaclass instance
}
});
mainPanel.add(playButton, gbc);
Within the actionPerformed() method, I instantiated a chooseaclass. You can do whatever you want from there.
I wrote this code off the cuff without an editor so it may contain syntax errors.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I have an ActionListener in other file & i want to use that ActionListener in my gui code which is
package GUI;
public class CheckButtonGUI {
private JPanel mainPanel;
private JButton One, Two, Three, Four;
JLabel buttonStatus;
public JPanel getGUI()
{
CheckButtonGUI cbg = new CheckButtonGUI();
mainPanel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(5, 5, 0, 0);
One = new JButton("1");
Two = new JButton("2");
Three = new JButton("3");
Four = new JButton("4");
buttonStatus = new JLabel("No Button Pressed");
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = GridBagConstraints.RELATIVE;
gbc.fill = GridBagConstraints.HORIZONTAL;
mainPanel.add(One,gbc);
gbc.gridx = 4;
//gbc.gridy = 0;
mainPanel.add(Two,gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = GridBagConstraints.RELATIVE;
gbc.fill = GridBagConstraints.HORIZONTAL;
mainPanel.add(Three,gbc);
gbc.gridwidth = 1;
gbc.fill = GridBagConstraints.NONE;
gbc.gridx = 4;
mainPanel.add(Four,gbc);
gbc.gridwidth=3;
gbc.gridx = 0;
gbc.gridy = 2;
mainPanel.add(buttonStatus,gbc);
// Action Listeners
CheckListener cli = new CheckListener(this);
One.addActionListener(cli);
Two.addActionListener(cli);
Three.addActionListener(cli);
Four.addActionListener(cli);
return mainPanel;
}
public void displayText(String str)
{
buttonStatus.setText(str);
}
private static void createAndShowGUI() {
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("[=] JTextField of Dreams [=]");
CheckButtonGUI demo = new CheckButtonGUI();
frame.setContentPane(demo.getGUI());
frame.setLocation(550, 350);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// We no longer manually re-size, we use pack to automatically size the frame.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
each & everything works fine but as soon as i try to add actionListener, the ECLIPSE IDE shows error. if i put null, error removes but then compiler doesn't work. i don't understand what i am doing wrong... Following is my actionListener, in case you need more details
package GUI;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class CheckListener implements ActionListener
{
//private ButtoncheckGUI bcg;
private CheckButtonGUI cbg;
public CheckListener(ButtoncheckGUI b)
{
//bcg = b;
cbg = b;
}
public void actionPerformed(ActionEvent action)
{
String op = action.getActionCommand();
if(op.equals("1"))
{
cbg.displayText("Button 1 was Pressed");
}else if (op.equals("2"))
{
cbg.displayText("Button 2 was Pressed");
}else if (op.equals("3"))
{
cbg.displayText("Button 3 was Pressed");
}else if (op.equals("4"))
{
cbg.displayText("Button 4 was Pressed");
}else
{
cbg.displayText("unExpected Input");
}
}
}
Actually the error was in actionListener's constructor's Parameter. i,somehow wrongly, instantiated actionListner's constructor with wrong 'gui model' object. As you can see, in my Controller class i.e. actionlistener there is ButtoncheckGUI b instantiated rather than CheckButtonGui b. Replaceing 'ButtoncheckGUI' with CheckButtonGUI resolved the issue!
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.