I'm trying to print which JPanel in JPanel array has been clicked using mouseEvent. How do I do that?
It gives me an error:
Local variable i defined in an enclosing scope must be final or effectively final
for(int i=0; i<count[0]; i++) {
p1[i] = new JPanel();
l1[lcount] = new JLabel("Panel "+(i+1));
p1[i].add(l1[lcount]);
panel_2.add(p1[i]);
lcount++;
p1[i].addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
System.out.println(i);
}
});
}
I want to extract the value of i and display it in another JLabel.
You can use the e.getSource() from you mouseEvent(). Just cast it to JPanel.
Here is an example.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MouseEventSource {
JFrame frame = new JFrame();
public static void main(String[] args) {
new MouseEventSource().start();
}
public void start() {
JPanel p1 = createPanel("Panel 1", Color.BLUE);
JPanel p2 = createPanel("Panel 2", Color.RED);
MyMouseListener ml = new MyMouseListener();
p1.addMouseListener(ml);
p2.addMouseListener(ml);
frame.setLayout(new FlowLayout());
frame.add(p1);
frame.add(p2);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public JPanel createPanel(String name, Color color) {
JPanel panel = new JPanel() {
public String toString() {
return name;
}
};
panel.setBackground(color);
panel.setPreferredSize(new Dimension(250, 250));
return panel;
}
private class MyMouseListener extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
// not really necessary to print toString()
JPanel panel = (JPanel) e.getSource();
System.out.println(panel);
}
}
}
Related
I'm having trouble with the functionality of dispose for my checkerboard (called Checkers) . For each checkerboard that I have, i want to be able to remove it by using dispose before calling another instance of my interface. Here is my progress so far:
Checkers class:
import java.awt.*;
import javax.swing.*;
import java.awt.Color.*;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import java.util.Random;
public class Checkers extends JFrame
{
Random random = new Random();
private final int ROWS = 2;
private final int COLS = 5;
private final int GAP = 2;
private final int NUM = ROWS * COLS;
private int i;
public int score;
private JPanel pane = new JPanel(new GridLayout(ROWS,COLS, GAP,GAP));
private JPanel pane2 = new JPanel();
private JPanel pane3 = new JPanel();
private JButton btn1 = new JButton("Play A Game");
private JButton btn2 = new JButton("Exit");
private JButton btn3 = new JButton("Easy");
private JButton btn4 = new JButton("Intermediate");
private JButton btn5 = new JButton("Difficult");
private JLabel lbl1 = new JLabel ("score: " + score);
private JLabel gameLost = new JLabel("You lose! You got: " + score + " points");
private MyPanel [] panel = new MyPanel[NUM];
private Color col1 = Color.RED;
private Color col2 = Color.WHITE;
private Color col3 = Color.GREEN;
private Color tempColor;
public Checkers()
{
super("Checkers");
setSize(600,600);
setVisible(true);
setBackground(Color.BLACK);
setBoard();
}
public void setBoard()
// roates colors on the checkbaord
{
for (int i = 0; i < panel.length; i++) {
panel[i] = new MyPanel(this);
pane.add(panel[i]);
if (i % COLS == 0) {
tempColor = col1;
col1 = col2;
col2 = tempColor;}
if (i % 2 == 0) {
panel[i].setBackground(col1);}
else {
panel[i].setBackground(col2);}
}
//pane background colour and the size of this pane.
pane.setBackground(Color.BLACK);
pane.setPreferredSize(new Dimension(300,300));
//pane background colour and size of this pane.
pane2.setBackground(Color.white);
pane2.setPreferredSize(new Dimension(300,300));
//directions on the board where these panes appear.
add(pane, BorderLayout.WEST);
add(pane2, BorderLayout.EAST);
pane2.add(lbl1);
pane2.setLayout(new BoxLayout(pane2, BoxLayout.PAGE_AXIS));
}
public void incrementScore(){
score++;
lbl1.setText("Score: " + Integer.toString(score));
}
//This is the method for resetting via dispose - only works once.
public void restartBoard(){
this.dispose();
new Checkers();
}
}
And also the MyPanel class
public class MyPanel extends JPanel implements MouseListener {
private final Checkers checkers;
public MyPanel(Checkers checkers) {
this.checkers = checkers;
addMouseListener(this);
}
#Override
public void mouseClicked(MouseEvent e) {
setBackground(Color.BLACK);
checkers.incrementScore();
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
}
EXPECTED RESULT - What i'd like to do is be able to close the current version of interface by using the dispose method, and then opening a new instance of said interface.
ACTUAL RESULT - When opening an interface, then calling dispose method, it will work once. once you try to remove the 2nd interface when creating a 3rd interface, dispose will not function, and I cant see why this is.
Any help is welcome.
For what it's worth, this is an MCVE that shows your likely problem:
import java.awt.Dimension;
import javax.swing.*;
public class CheckersTest {
private static void createAndShowGui() {
Checkers checkers = new Checkers();
JButton restartButton = new JButton("Restart");
restartButton.addActionListener(event -> checkers.restartBoard());
JPanel restartPanel = new JPanel();
restartPanel.setPreferredSize(new Dimension(400, 400));
restartPanel.add(restartButton);
JFrame frame = new JFrame("Checkers Test");
frame.add(restartPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
class Checkers extends JFrame {
public Checkers() {
setPreferredSize(new Dimension(200, 200));
pack();
setLocationByPlatform(true);
setVisible(true);
}
public void restartBoard(){
this.dispose();
new Checkers();
}
}
The restart button refers to the original Checkers instance and so will not close any new instances created. The solution would be to get the restart method out of Checkers, create a Checkers field, and make sure the restart method refers to the visible Checkers instance:
import java.awt.Dimension;
import javax.swing.*;
public class CheckersTest {
private static Checkers checkers = new Checkers(); // holds reference
private static void restartBoard() {
if (checkers != null) {
checkers.dispose();
checkers = new Checkers(); // assign to reference field
}
}
private static void createAndShowGui() {
// !! Checkers checkers = new Checkers();
JButton restartButton = new JButton("Restart");
// !! restartButton.addActionListener(event -> checkers.restartBoard());
restartButton.addActionListener(event -> restartBoard());
JPanel restartPanel = new JPanel();
restartPanel.setPreferredSize(new Dimension(400, 400));
restartPanel.add(restartButton);
JFrame frame = new JFrame("Checkers Test");
frame.add(restartPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
class Checkers extends JFrame {
public Checkers() {
setPreferredSize(new Dimension(200, 200));
pack();
setLocationByPlatform(true);
setVisible(true);
}
}
Notes:
Again a much better design is not to swap JFrames but rather JPanel views
Note that the MCVE has code that reproduces the problem but avoids code not related to the problem. So it shows the restartBoard method, it compiles, but avoids game code since this is not relevant to the problem.
So I'm working on making a database system built on top of a Java Swing GUI... I have one button that works to add a person/thing to a vector (in this case the database):
// Database
Vector<String> db = new Vector<String>();
Here is the button's actionlistener to add:
new ActionListener() {
public void actionPerformed(ActionEvent e) {
String newStudent = student.getText();
db.addElement(newStudent);
This part all seems to be working fine, however, when I go to print out the vector on a JTextArea using a string buffer, there are odd spacing issues in the text on the JTextArea
Here is the StringBuffer and section where I print the vector onto the JTextArea:
StringBuffer dbb = new StringBuffer();
for (int i = 0; i < db.size(); i++) {
dbb.append(db.get(i) + '\n');
}
// printDB is the JTextArea
printDB.setText(dbb.toString());
add(printDB);
Screenshot of spacing issues:
Screenshot
Any Ideas on what might be causing this? The spacing seems to be linear as well (1space, 2spaces, 3spaces...)
Link to full project if needed (Sorry for bad code in general lol i'm just beginning): Full Code
Sorry if linear isn't the right word btw I couldn't think of another way to describe it
Code:
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.util.*;
import java.util.Vector.*;
import javax.swing.*;
public class Database extends JFrame implements ActionListener, EventListener {
// Database
Vector<String> db = new Vector<String>();
// Main Menu Buttons:
JButton addStudent = new JButton("Add Student");
JButton deleteStudent = new JButton("Delete Button");
JButton deleteAll = new JButton("Delete All Students");
JButton printAll = new JButton("Print Database");
JTextArea welcome = new JTextArea("Welcome!");
// Add Student Menu:
JTextField student = new JTextField();
JButton submit = new JButton("Add Student");
// Print Students
JTextArea printDB = new JTextArea();
JButton returnMenu = new JButton("Return to Menu");
public Database() {
super("DatabaseGUI");
setSize(800, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(null);
setResizable(false);
welcome.setBackground(this.getForeground());
add(welcome);
welcome.setSize(60, 15);
welcome.setLocation(386, 300);
add(addStudent);
addStudent.setSize(150, 50);
addStudent.setLocation(25, 100);
add(deleteStudent);
deleteStudent.setSize(150, 50);
deleteStudent.setLocation(625, 100);
add(deleteAll);
deleteAll.setLocation(225, 100);
deleteAll.setSize(150, 50);
add(printAll);
printAll.setLocation(425, 100);
printAll.setSize(150, 50);
addStudent.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
welcome.setVisible(false);
addStudent.setVisible(false);
deleteStudent.setVisible(false);
deleteAll.setVisible(false);
printAll.setVisible(false);
add(student);
add(submit);
submit.setVisible(true);
submit.setSize(150, 30);
submit.setLocation(425, 250);
student.setVisible(true);
student.setSize(150, 30);
student.setLocation(275, 250);
submit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String newStudent = student.getText();
db.addElement(newStudent);
student.setText(null);
student.setVisible(false);
submit.setVisible(false);
welcome.setVisible(true);
addStudent.setVisible(true);
deleteStudent.setVisible(true);
deleteAll.setVisible(true);
printAll.setVisible(true);
}
});
}
});
printAll.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
welcome.setVisible(false);
addStudent.setVisible(false);
deleteStudent.setVisible(false);
deleteAll.setVisible(false);
printAll.setVisible(false);
StringBuffer dbb = new StringBuffer();
for (int i = 0; i < db.size(); i++) {
dbb.append(db.get(i) + '\n');
}
printDB.setText(dbb.toString());
add(printDB);
printDB.setSize(300, 400);
printDB.setEditable(false);
printDB.setLocation(100, 100);
printDB.setVisible(true);
add(returnMenu);
returnMenu.setVisible(true);
returnMenu.setSize(200, 30);
returnMenu.setLocation(500, 400);
returnMenu.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
returnMenu.setVisible(false);
printDB.setVisible(false);
welcome.setVisible(true);
addStudent.setVisible(true);
deleteStudent.setVisible(true);
deleteAll.setVisible(true);
printAll.setVisible(true);
}
});
}
});
setVisible(true);
}
public static void main(String[] args) {
Database student = new Database();
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}
You're adding an ActionListener to the submit button repeatedly within the addStudent ActionListener, meaning as addStudent is pressed, more and more ActionListeners will be added to submit and this is not what you want.
Suggestions:
Add an ActionListener just once to your JButtons and not within other event listeners which may be called multiple times. Consider adding all ActionListeners within your class constructor.
Side recs:
Don't use absolute positioning and null layouts. 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.
Learn how to use and then use CardLayout to allow you to cleanly and easily swap your views.
For example,
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
#SuppressWarnings("serial")
public class Database2 extends JPanel {
// constants for the cards
public static final String WELCOME = "welcome";
public static final String ADD_STUDENT = "add student";
public static final String DISPLAY_DATA = "display data";
private JTextArea displayTextArea = new JTextArea(15, 20);
private JTextField addStudentField = new JTextField(10);
private CardLayout cardLayout = new CardLayout();
private List<String> db = new ArrayList<>();
public Database2() {
// prepare JTextArea
displayTextArea.setWrapStyleWord(true);
displayTextArea.setLineWrap(true);
displayTextArea.setFocusable(false);
// set layout as CardLayout and add all JPanels with constants
setLayout(cardLayout);
add(createWelcomePanel(), WELCOME);
add(createAddStudentPanel(), ADD_STUDENT);
add(createDisplayDataPanel(), DISPLAY_DATA);
}
private JPanel createWelcomePanel() {
ShowStudentPanelAction showStudentAction = new ShowStudentPanelAction("Add Student");
DisplayDataAction displayDataAction = new DisplayDataAction("Display Data");
JButton addStudentButton = new JButton(showStudentAction);
JButton displayDataButton = new JButton(displayDataAction);
JPanel topPanel = new JPanel(new GridLayout(1, 0, 5, 0));
topPanel.add(addStudentButton);
topPanel.add(displayDataButton);
topPanel.add(new JButton(new ExitAction("Exit", KeyEvent.VK_X)));
JLabel welcomeLabel = new JLabel("Welcome", SwingConstants.CENTER);
// make JLabel text bigger
welcomeLabel.setFont(welcomeLabel.getFont().deriveFont(Font.BOLD, 42f));
// and give it a border 30 points wide
int ebGap = 30;
welcomeLabel.setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap,
ebGap, ebGap));
JPanel welcomePanel = new JPanel(new BorderLayout());
ebGap = 4;
welcomePanel.setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap));
welcomePanel.add(topPanel, BorderLayout.PAGE_START);
welcomePanel.add(welcomeLabel, BorderLayout.CENTER);
return welcomePanel;
}
private JPanel createAddStudentPanel() {
AddStudentAction addStudentAction = new AddStudentAction("Add Student");
addStudentField.setAction(addStudentAction);
JPanel addStudentPanel = new JPanel();
addStudentPanel.add(addStudentField);
addStudentPanel.add(new JButton(addStudentAction));
return addStudentPanel;
}
private JPanel createDisplayDataPanel() {
JPanel displayDataPanel = new JPanel();
JScrollPane scrollPane = new JScrollPane(displayTextArea);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
displayDataPanel.add(scrollPane);
displayDataPanel.add(new JButton(new ReturnToWelcomeAction("Return")));
return displayDataPanel;
}
private class ShowStudentPanelAction extends AbstractAction {
public ShowStudentPanelAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
cardLayout.show(Database2.this, ADD_STUDENT);
addStudentField.requestFocusInWindow();
addStudentField.selectAll();
}
}
private class DisplayDataAction extends AbstractAction {
public DisplayDataAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
StringBuilder sb = new StringBuilder();
for (String studentName : db) {
sb.append(studentName + "\n");
}
displayTextArea.setText(sb.toString());
cardLayout.show(Database2.this, DISPLAY_DATA);
}
}
private class AddStudentAction extends AbstractAction {
public AddStudentAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
String studentText = addStudentField.getText();
db.add(studentText);
cardLayout.show(Database2.this, WELCOME);
}
}
private class ReturnToWelcomeAction extends AbstractAction {
public ReturnToWelcomeAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
cardLayout.show(Database2.this, WELCOME);
}
}
private class ExitAction extends AbstractAction {
public ExitAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
Window window = SwingUtilities.getWindowAncestor(Database2.this);
if (window != null) {
window.dispose();
}
}
}
private static void createAndShowGui() {
Database2 mainPanel = new Database2();
JFrame frame = new JFrame("Database2");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
I have a JFrame which contains 2 JPanel subclass and 2 JLabel in BorderLayout. One of the JPanel contains JButtons and the other is used for displaying graphics. The JLabels are in north and south, the button JPanel in the west and the display JPanel in center.
The display JPanel requires constant refresh, so i invoke its repaint() method via the action event generated by swing timer. I also override its paintComponent() method to do my drawings.
Instead of displaying what i have drawn, the "content of the JFrame" is being drawn onto the display JPanel. I am aware that i can simply "clear" the display JPanel by using g.fillRect() or super.paintComponent() before doing my drawings.
I am just curious why this happens.
i'm using jdk 1.6u27. below is my code:
package test;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class Main {
public static void main(String[] args) {
Simulation sim = new Simulation();
}
}
class Simulation extends JFrame {
public JLabel state;
private JLabel id;
private ButtonPanel control;
private Display display;
public Simulation() {
id = new JLabel("Test");
state = new JLabel("Test");
control = new ButtonPanel();
display = new Display(this);
this.setLayout(new BorderLayout());
this.add(id, BorderLayout.NORTH);
this.add(control, BorderLayout.WEST);
this.add(display, BorderLayout.CENTER);
this.add(state, BorderLayout.SOUTH);
this.setSize(500, 600);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public ButtonPanel getControl() {
return this.control;
}
}
class ButtonPanel extends JPanel implements ActionListener {
public JButton b[] = new JButton[8];
public boolean bp[] = new boolean[8];
public ButtonPanel() {
this.setLayout(new GridLayout(8, 1));
for (int i = 0; i < b.length; i++) {
b[i] = new JButton(""+i);
b[i].addActionListener(this);
bp[i] = false;
this.add(b[i]);
}
}
public void actionPerformed(ActionEvent e) {
//do something
}
}
class Display extends JPanel implements ActionListener {
private Timer tm;
private int yco;
private Simulation sim;
public Display(Simulation sim) {
tm = new Timer(100, this);
tm.start();
yco = 0;
this.sim = sim;
}
#Override
public void paintComponent(Graphics g) {
//draw something
g.drawLine(0, yco, 100, 100);
}
public void actionPerformed(ActionEvent e) {
yco ++;
this.repaint();
}
}
Without super.paintComponent(g), the result depends on your platform's default for the opacity property of the JPanel UI delegate, PanelUI. Mine happens to be true, but you can experiment on your platform, as suggested below.
Addendum: "If you do not honor the opaque property you will likely see visual artifacts."—paintComponent(). The artifact you observe will vary by platform, but it is not atypical. In effect, you are breaking the promise to draw every pixel, and you see whatever is left over in some buffer.
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
public class Main {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
Simulation sim = new Simulation();
}
});
}
}
class Simulation extends JFrame {
public JCheckBox state;
private JLabel id;
private ButtonPanel control;
private Display display;
public Simulation() {
id = new JLabel("Test");
state = new JCheckBox("Opaque");
control = new ButtonPanel();
display = new Display(this);
this.setLayout(new BorderLayout());
this.add(id, BorderLayout.NORTH);
this.add(control, BorderLayout.WEST);
this.add(display, BorderLayout.CENTER);
this.add(state, BorderLayout.SOUTH);
state.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
display.setOpaque(e.getStateChange() == ItemEvent.SELECTED);
}
});
state.setSelected(true);
this.pack();
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public ButtonPanel getControl() {
return this.control;
}
}
class ButtonPanel extends JPanel {
private static final int N = 8;
private List<JToggleButton> list = new ArrayList<JToggleButton>(N);
public ButtonPanel() {
this.setLayout(new GridLayout(0, 1));
for (int i = 0; i < N; i++) {
final JToggleButton b = new JToggleButton(String.valueOf(i));
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//System.out.println(b.isSelected());
}
});
list.add(b);
this.add(b);
}
}
}
class Display extends JPanel {
private Simulation sim;
private Timer tm;
private int yco;
public Display(Simulation sim) {
this.setPreferredSize(new Dimension(320, 320));
this.setOpaque(true);
this.sim = sim;
tm = new Timer(100, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
yco++;
repaint();
}
});
tm.start();
}
#Override
public void paintComponent(Graphics g) {
//super.paintComponent(g);
g.drawLine(0, yco, getWidth() / 2, getHeight() / 2);
}
}
I am writing a program for a black jack game. It is an assignment we are not to use gui's but I am doing it for extra credit I have created two frames ant they are working. On the second frame I want to be able to switch back to the first when a button is pressed. How do I do this?
first window.............
import javax.swing.* ;
import java.awt.event.* ;
import java.awt.* ;
import java.util.* ;
public class BlackJackWindow1 extends JFrame implements ActionListener
{
private JButton play = new JButton("Play");
private JButton exit = new JButton("Exit");
private JPanel pane=new JPanel();
private JLabel lbl ;
public BlackJackWindow1()
{
super();
JPanel pane=new JPanel();
setTitle ("Black Jack!!!!!") ;
JFrame frame = new JFrame("");
setVisible(true);
setSize (380, 260) ;
setLocation (450, 200) ;
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE) ;
setLayout(new FlowLayout());
play = new JButton("Start");
exit = new JButton("exit");
lbl = new JLabel ("Welcome to Theodores Black Jack!!!!!");
add (lbl) ;
add(play, BorderLayout.CENTER);
play.addActionListener (this);
add(exit,BorderLayout.CENTER);
exit.addActionListener (this);
}
#Override
public void actionPerformed(ActionEvent event)
{
// TODO Auto-generated method stub
BlackJackWindow2 bl = new BlackJackWindow2();
if (event.getSource() == play)
{
bl.BlackJackWindow2();
}
else if(event.getSource() == exit){
System.exit(0);
}
}
second window....
import javax.swing.* ;
import java.awt.event.* ;
import java.awt.* ;
import java.util.* ;
public class BlackJackWindow2 extends JFrame implements ActionListener
{
private JButton hit ;
private JButton stay ;
private JButton back;
//private JLabel lbl;
public void BlackJackWindow2()
{
// TODO Auto-generated method stub
JPanel pane=new JPanel();
setTitle ("Black Jack!!!!!") ;
JFrame frame = new JFrame("");
setVisible(true);
setSize (380, 260) ;
setLocation (450, 200) ;
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE) ;
setLayout(new FlowLayout());
hit = new JButton("Hit");
stay = new JButton("stay");
back = new JButton("return to main menu");
// add (lbl) ;
add(hit, BorderLayout.CENTER);
hit.addActionListener (this) ;
add(stay,BorderLayout.CENTER);
stay.addActionListener (this) ;
add(back,BorderLayout.CENTER);
back.addActionListener (this) ;
}
#Override
public void actionPerformed(ActionEvent event)
{
// TODO Auto-generated method stub
BlackJackWindow1 bl = new BlackJackWindow1();
if (event.getSource() == hit)
{
//code for the game goes here i will complete later
}
else if(event.getSource() == stay){
//code for game goes here i will comeplete later.
}
else
{
//this is where i want the frame to close and go back to the original.
}
}
}
The second frame needs a reference to the first frame so that it can set the focus back to the first frame.
Also your classes extend JFrame but they are also creating other frames in their constructors.
A couple of suggestions:
You're adding components to a JPanel that uses FlowLayout but are using BorderLayout constants when doing this which you shouldn't do as it doesn't make sense:
add(play, BorderLayout.CENTER);
Rather, if using FlowLayout, just add the components without those constants.
Also, rather than swap JFrames, you might want to consider using a CardLayout and swapping veiws in a single JFrame. For instance:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FooBarBazDriver {
private static final String INTRO = "intro";
private static final String GAME = "game";
private CardLayout cardlayout = new CardLayout();
private JPanel mainPanel = new JPanel(cardlayout);
private IntroPanel introPanel = new IntroPanel();
private GamePanel gamePanel = new GamePanel();
public FooBarBazDriver() {
mainPanel.add(introPanel.getMainComponent(), INTRO);
mainPanel.add(gamePanel.getMainComponent(), GAME);
introPanel.addBazBtnActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
cardlayout.show(mainPanel, GAME);
}
});
gamePanel.addBackBtnActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
cardlayout.show(mainPanel, INTRO);
}
});
}
private JComponent getMainComponent() {
return mainPanel;
}
private static void createAndShowUI() {
JFrame frame = new JFrame("Foo Bar Baz");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new FooBarBazDriver().getMainComponent());
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 IntroPanel {
private JPanel mainPanel = new JPanel();
private JButton baz = new JButton("Baz");
private JButton exit = new JButton("Exit");
public IntroPanel() {
mainPanel.setLayout(new FlowLayout());
baz = new JButton("Start");
exit = new JButton("exit");
mainPanel.add(new JLabel("Hello World"));
mainPanel.add(baz);
mainPanel.add(exit);
exit.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Window win = SwingUtilities.getWindowAncestor(mainPanel);
win.dispose();
}
});
}
public void addBazBtnActionListener(ActionListener listener) {
baz.addActionListener(listener);
}
public JComponent getMainComponent() {
return mainPanel;
}
}
class GamePanel {
private static final Dimension MAIN_SIZE = new Dimension(400, 200);
private JPanel mainPanel = new JPanel();
private JButton foo;
private JButton bar;
private JButton back;
public GamePanel() {
foo = new JButton("Foo");
bar = new JButton("Bar");
back = new JButton("return to main menu");
mainPanel.add(foo);
mainPanel.add(bar);
mainPanel.add(back);
mainPanel.setPreferredSize(MAIN_SIZE);
}
public JComponent getMainComponent() {
return mainPanel;
}
public void addBackBtnActionListener(ActionListener listener) {
back.addActionListener(listener);
}
}
Since I had to test it myself if it is in fact so easy to implement, I built this simple example. It demonstrates a solution to your problem. Slightly inspired by #jzd's answer (+1 for that).
import java.awt.Color;
import java.awt.HeadlessException;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class FocusChangeTwoFrames
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
createGUI();
}
});
}
private static void createGUI() throws HeadlessException
{
final JFrame f2 = new JFrame();
f2.getContentPane().setBackground(Color.GREEN);
final JFrame f1 = new JFrame();
f1.getContentPane().setBackground(Color.RED);
f1.setSize(400, 300);
f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f1.setVisible(true);
MouseListener ml = new MouseAdapter()
{
#Override
public void mousePressed(MouseEvent e)
{
if(f1.hasFocus())
f2.requestFocus();
else
f1.requestFocus();
}
};
f1.addMouseListener(ml);
f2.setSize(400, 300);
f2.setLocation(200, 150);
f2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f2.setVisible(true);
f2.addMouseListener(ml);
}
}
Enjoy, Boro.
I have created a divider in JSplitPane. I am unable to set the color of divider. I want to set the color of divider. Please help me how to set color of that divider.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class SplitPaneDemo {
JFrame frame;
JPanel left, right;
JSplitPane pane;
int lastDividerLocation = -1;
public static void main(String[] args) {
SplitPaneDemo demo = new SplitPaneDemo();
demo.makeFrame();
demo.frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
demo.frame.show();
}
public JFrame makeFrame() {
frame = new JFrame();
// Create a horizontal split pane.
pane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
left = new JPanel();
left.setBackground(Color.red);
pane.setLeftComponent(left);
right = new JPanel();
right.setBackground(Color.green);
pane.setRightComponent(right);
JButton showleft = new JButton("Left");
showleft.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Container c = frame.getContentPane();
if (pane.isShowing()) {
lastDividerLocation = pane.getDividerLocation();
}
c.remove(pane);
c.remove(left);
c.remove(right);
c.add(left, BorderLayout.CENTER);
c.validate();
c.repaint();
}
});
JButton showright = new JButton("Right");
showright.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Container c = frame.getContentPane();
if (pane.isShowing()) {
lastDividerLocation = pane.getDividerLocation();
}
c.remove(pane);
c.remove(left);
c.remove(right);
c.add(right, BorderLayout.CENTER);
c.validate();
c.repaint();
}
});
JButton showboth = new JButton("Both");
showboth.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Container c = frame.getContentPane();
c.remove(pane);
c.remove(left);
c.remove(right);
pane.setLeftComponent(left);
pane.setRightComponent(right);
c.add(pane, BorderLayout.CENTER);
if (lastDividerLocation >= 0) {
pane.setDividerLocation(lastDividerLocation);
}
c.validate();
c.repaint();
}
});
JPanel buttons = new JPanel();
buttons.setLayout(new GridBagLayout());
buttons.add(showleft);
buttons.add(showright);
buttons.add(showboth);
frame.getContentPane().add(buttons, BorderLayout.NORTH);
pane.setPreferredSize(new Dimension(400, 300));
frame.getContentPane().add(pane, BorderLayout.CENTER);
frame.pack();
pane.setDividerLocation(0.5);
return frame;
}
}
Thanks
Sunil kumar Sahoo
Or, since the divider is a container, you can do the following:
dividerContainer = (BasicSplitPaneDivider) splitPane.getComponent(2);
Component leftBtn = dividerContainer.getComponent(0);
Component rightBtn = dividerContainer.getComponent(1);
dividerContainer.setBackground(Color.white);
dividerContainer.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 4));
dividerContainer.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
dividerContainer.add(toolbar);
dividerContainer.setDividerSize(toolbar.getPreferredSize().height);
This code works for me:
splitPane.setUI(new BasicSplitPaneUI() {
public BasicSplitPaneDivider createDefaultDivider() {
return new BasicSplitPaneDivider(this) {
public void setBorder(Border b) {
}
#Override
public void paint(Graphics g) {
g.setColor(Color.GREEN);
g.fillRect(0, 0, getSize().width, getSize().height);
super.paint(g);
}
};
}
});
splitPane.setBorder(null);
You can change divider color "g.setColor(new Color(R,G,B))".
This worked for me fine.First you are creating JFrame with it's normal methods such as setDefaultCloseOperation(), setBounds(), getContentPane(). Then create an object from your class then use that to call all the other methods through out the program, in this case I created object called app. One thing you have to keep in mind is that don't forget to use ActionListener e.
Also color changes must go with setBackground() function, while you getting the values from getSource() for the color change.
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class Main implements ActionListener {
private static void createAndShowGUI() {
Main app=new Main();
// make frame..
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("I am a JFrame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(20,30,300,120);
frame.setLayout(null);
//Create a split pane
JSplitPane myPane = new JSplitPane();
myPane.setOpaque(true);
myPane.setDividerLocation(150);
app.right = new JPanel();
app.right.setBackground(new Color(255,0,0));
app.left = new JPanel();
app.left.setBackground(new Color(0,255,0));
app.left.setLayout(null);
myPane.setRightComponent(app.right);
myPane.setLeftComponent(app.left);
// make buttons
app.butt1=new JButton("Red");
app.butt2=new JButton("Blue");
app.butt3=new JButton("Green");
// add and size buttons
app.left.add(app.butt1);
app.butt1.setBounds(10,10, 100,20);
app.left.add(app.butt2);
app.butt2.setBounds(10,30, 100,20);
app.left.add(app.butt3);
app.butt3.setBounds(10,50, 100,20);
// set up listener
app.butt1.addActionListener(app);
app.butt2.addActionListener(app);
app.butt3.addActionListener(app);
frame.setContentPane(myPane);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
// check which button and act accordingly
if (e.getSource()==butt1)
right.setBackground(new Color(255,0,0));
if (e.getSource()==butt2)
right.setBackground(new Color(0,0,255));
if (e.getSource()==butt3)
right.setBackground(new Color(0,255,0));
}
public static void main(String[] args) {
// start off..
try {
UIManager.setLookAndFeel(
"javax.swing.plaf.metal.MetalLookAndFeel" );
}
catch (Exception e)
{
System.out.println("Cant get laf");
}
Object a[]= UIManager.getInstalledLookAndFeels();
for (int i=0; i<a.length; i++)
System.out.println(a[i]);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
// application object fields
int clickCount=0;
JLabel label;
JButton butt1;
JButton butt2;
JButton butt3;
JPanel left;
JPanel right;
}