Giving mulitple Jbuttons the same actionListener - java

I have written a 2x2x2 rubiks cube solver and I want to make the experience for the user entering their cube better, currently they enter numbers which are assigned to colors of the cube. For example 0 could represent white, 1 could represent yellow etc. I have been working on a GUI that is a 2d cube made of buttons that when they are clicked change loop over an array of colors. This is what I have so far but I can't get the actionListener to apply to all the buttons.
public static void main(String[] args) {
final int WINDOW_HEIGHT = 500;
final int WINDOW_WIDTH = 700;
//create a window
window.setTitle("First Window");
window.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
window.setResizable(false);
allButtons();
}
private static void allButtons(){
panel.setLayout(null);
window.add(panel);
final JButton button[]=new JButton[23];
for(int i=0;i<button.length;i++){
button[i] = new JButton();
}
panel.add(button[0]);
button[0].setBounds(30, 30, 60, 60);
final Color[] ColorArray = {Color.WHITE, Color.ORANGE,Color.GREEN,Color.RED,Color.BLUE,Color.YELLOW};
button[0].addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
final int stickerNum = 24;
if(stickerNum <= 3){
for(Color i : ColorArray){
button[0].setBackground(i);
cube[Side][0] = 0;
}
}
}
});
}

Just assign the ActionListener instance to a variable and add that to JButtons in a loop.
public static void main(String[] args) {
final int WINDOW_HEIGHT = 500;
final int WINDOW_WIDTH = 700;
//create a window
window.setTitle("First Window");
window.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
window.setResizable(false);
allButtons();
}
private static void allButtons(){
panel.setLayout(null);
window.add(panel);
final JButton button[]=new JButton[23];
for(int i=0;i<button.length;i++){
button[i] = new JButton();
}
panel.add(button[0]);
button[0].setBounds(30, 30, 60, 60);
final Color[] ColorArray = {Color.WHITE, Color.ORANGE,Color.GREEN,Color.RED,Color.BLUE,Color.YELLOW};
ActionListener actionListener = new ActionListener(){
public void actionPerformed(ActionEvent e){
final int stickerNum = 24;
if(stickerNum <= 3){
for(Color i : ColorArray){
button[0].setBackground(i);
cube[Side][0] = 0;
}
}
}
};
for(int i=0;i<button.length;i++){
button[i].addActionListener( actionListener);
}
}

You can just create an ButtonListener class like below which stores an index. Then you just add a new instance of the listener to every button.
public static void main(String[] args) {
final int WINDOW_HEIGHT = 500;
final int WINDOW_WIDTH = 700;
//create a window
window.setTitle("First Window");
window.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
window.setResizable(false);
allButtons();
}
private static void allButtons() {
panel.setLayout(null);
window.add(panel);
final JButton button[]=new JButton[23];
for(int i=0;i<button.length;i++){
button[i] = new JButton();
}
panel.add(button[0]);
button[0].setBounds(30, 30, 60, 60);
final Color[] ColorArray = {Color.WHITE, Color.ORANGE,Color.GREEN,Color.RED,Color.BLUE,Color.YELLOW};
class ButtonListener implements ActionListener {
private int buttonIndex;
public ButtonListener(int buttonIndex) {
this.buttonIndex = buttonIndex;
}
#Override
public void actionPerformed(ActionEvent e) {
final int stickerNum = 24;
if(stickerNum <= 3){
for(Color i : ColorArray){
button[buttonIndex].setBackground(i);
cube[Side][0] = 0;
}
}
}
}
for(int i = 0; i < button.length; i++) {
button[i].addActionListener(new ButtonListener(i));
}
}

Related

How to input values or phrases on a window?

I'm trying to write a program that solves an equation for a school project, but I can't figure out how to create a space for writing in the screen instead of eclipse's console. Like, creating a space in the bottom of the window so the user can input the requested values and the program can read that and make the equation, finally showing the user the final result.
public class Main extends Canvas implements Runnable{
public static JFrame frame;
private Thread thread;
private boolean isRunning = true;
private final int WIDTH = 160;
private final int HEIGHT = 120;
private final int SCALE = 4;
private BufferedImage image;
public Main() {
setPreferredSize(new Dimension(WIDTH*SCALE,HEIGHT*SCALE));
initFrame();
image = new BufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_INT_RGB);
}
public void initFrame() {
frame = new JFrame("Tempo de Queda (FĂ­sica)");
frame.add(this);
frame.setResizable(false);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public synchronized void start() {
thread = new Thread(this);
isRunning = true;
thread.start();
}
public synchronized void stop() {
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Main main = new Main();
main.start();}
public void tick() {
}
public void render() {
BufferStrategy bs = getBufferStrategy();
if(bs==null) {
createBufferStrategy(3);
return;
}
Graphics g = image.getGraphics();
//Back Ground---------------------------------------
g.setColor(new Color(19,19,19));
g.fillRect(0,0,WIDTH,HEIGHT);
g = bs.getDrawGraphics();
g.drawImage(image,0,0,WIDTH*SCALE,HEIGHT*SCALE,null);
//Back Ground---------------------------------------
g.setFont(new Font("Arial",Font.PLAIN,20));
g.setColor(Color.green);
g.drawString("Write Here: ", 5,20);
bs.show();
}
public void run() {
long lastTime = System.nanoTime();
double amountOfTicks = 60.0;
double ns = 1000000000 / amountOfTicks;
double delta = 0;
int frames = 0;
double timer = System.currentTimeMillis();
while(isRunning) {
long now = System.nanoTime();
delta+= (now-lastTime) / ns;
lastTime = now;
if(delta >= 1) {
tick();
render();
frames++;
delta--;
}
if(System.currentTimeMillis() - timer >= 1000) {
System.out.println("FPS: "+frames);
frames = 0;
timer+=1000;
}
}
}
}
So in your case, I'd make some additions to the initFrame method. Specifically, you'll want to add a JPanel to it.
JPanel panel = new JPanel();
frame.add(panel);
Then, define your JTextFields, a JButton and any JLabels to go with them. Java will want you to define any that you're messing with the text value as "final." The other components are ok to set as "final" if you don't plan on reinitializing them:
final JLabel labelX = new JLabel();
final JLabel labelY = new JLabel();
final JLabel output = new JLabel();
final JTextField inputX = new JTextField(5);
final JTextField inputY = new JTextField(5);
final JButton button = new JButton("multiply");
Setting the text of any labels is a good idea:
labelX.setText("X");
labelY.setText("Y");
output.setText("NaN");
Then add them all to the panel:
panel.add(labelX);
panel.add(inputX);
panel.add(labelY);
panel.add(inputY);
panel.add(button);
panel.add(output);
Finally, you'll need to add a listener for the button action. This is where you'll process your inputs and display the output.
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
float valueX = 0;
float valueY = 0;
boolean validInputs = true;
try {
valueX = Float.parseFloat(inputX.getText());
valueY = Float.parseFloat(inputY.getText());
} catch (NumberFormatException ex) {
output.setText("Invalid input value(s)");
validInputs = false;
}
if (validInputs) {
//multiply
float result = valueX * valueY;
output.setText(Float.toString(result));
}
}
});
Running that should give you something like this:
Link to Github: FloatMathGUI

Show an Array of JButtons one after another with a timer [JAVA SWING]

I am making a Color game in which when I click on start a chain of colors will be shown. Now I have to click on my 4 color buttons and match the shown chain.
If I win, the chain adds a color (Level up) if I lose the chain loses a color (Level down).
My problems right now :
If I overlap the shown colors to match, I will only see the first index of the Array. I need to make it to show all Indexes of the JButton [] like every 2 seconds. I tried it with timer but it still show only the first one.
If I level up, I can add a color to the need to match array, but If I level down, I cant delete the last added color. I know there is no way to remove something from an Array, but is there a workaround. Right now I am making the player lose completely if he doesnt match the scheme.
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.*;
public class Farbgedaechtnisspiel {
private static int startLevel = 1;
private static int gameLevel = 3;
private static List<Integer> gameArray = new ArrayList<>();
private static List<Integer> userArray = new ArrayList<>();
private static int save = 0;
private static int count = 0;
private static JButton [] b;
private static final Color red = new Color(255, 0, 0);
private static final Color green = new Color(0, 255, 0);
private static final Color blue = new Color(0, 0, 255);
private static final Color yellow = new Color(255, 255, 0);
private static JFrame frame = new JFrame("Farbgedächtnisspiel");
private static JLabel levelTxt;
public static void main(String[] args) {
// create mainframe
new Farbgedaechtnisspiel();
}
public Farbgedaechtnisspiel () {
createFrame(frame);
levelTxt = new JLabel("Level: " + startLevel);
frame.add(levelTxt);
levelTxt.setFont(new Font("Times New Roman", Font.ITALIC, 40));
// create 4 color buttons + start/exit
b = new JButton[7];
for(int i = 0;i<b.length;i++){
b[i] = new JButton();
frame.add(b[i]);
}
// create button layout
createButtons();
// button listeners
b[4].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// start Game -> show taskArray
levelTxt.setBounds(550, 200, 200, 200);
startGame(gameLevel);
}});
b[5].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
b[0].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
userArray.add(1);
save++;
}
}
);
b[1].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
userArray.add(2);
save++;
}
});
b[2].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
userArray.add(3);
save++;
}
});
b[3].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
userArray.add(4);
save++;
}
});
b[6].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
boolean result = compareArrays(userArray, gameArray);
if (result){
gameLevel++;
save = 0;
startLevel++;
levelTxt.setText("Level: " + startLevel);
} else {
JOptionPane.showMessageDialog(frame, "Sie haben verloren");
new Farbgedaechtnisspiel();
System.exit(1);
}
startGame(gameLevel);
}
});
// make frame visible
frame.setVisible(true);
}
public static void startGame(int gameLevel){
int x = 100;
JButton [] tmp = new JButton[gameLevel];
for(int i = 0;i<tmp.length;i++) {
tmp[i] = new JButton();
tmp[i].setBackground(randomColor());
tmp[i].setOpaque(true);
tmp[i].setBorderPainted(false);
frame.add(tmp[i]);
if (tmp[i].getBackground() == red) {
gameArray.add(1);
} else if (tmp[i].getBackground() == blue) {
gameArray.add(2);
} else if (tmp[i].getBackground() == green) {
gameArray.add(3);
} else if (tmp[i].getBackground() == yellow) {
gameArray.add(4);
}
}
for (int i = 0; i < tmp.length; i++) {
tmp[i].setBounds(x, 50, 100, 100);
x+=100;
}
// for (int i = 0; i < tmp.length; i++) {
// tmp[i].setBounds(450, 50, 300, 299);
// x += 100;
// }
}
public static void createButtons() {
int x = 0;
for (int i = 0; i < b.length; i++) {
b[i].setBounds(x, 0, 200, 200);
x += 200;
}
b[0].setBackground(red);
b[0].setOpaque(true);
b[0].setBorderPainted(false);
b[1].setBackground(blue);
b[1].setOpaque(true);
b[1].setBorderPainted(false);
b[2].setBackground(green);
b[2].setOpaque(true);
b[2].setBorderPainted(false);
b[3].setBackground(yellow);
b[3].setOpaque(true);
b[3].setBorderPainted(false);
b[4].setBounds(150,600,300,200);
b[4].setText("Start");
b[5].setBounds(450, 600, 300, 200);
b[5].setText("Beenden");
b[6].setBounds(750, 600, 300, 200);
b[6].setText("Continue");
b[0].setBounds(200, 400, 200, 200);
b[1].setBounds(400, 400, 200, 200);
b[2].setBounds(600, 400, 200, 200);
b[3].setBounds(800, 400, 200, 200);
}
public static boolean compareArrays(List<Integer> userArray, List<Integer> gameArray){
return userArray.equals(gameArray);
}
public static void createFrame(JFrame frame){
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(1200,800);
frame.setLocationRelativeTo(null);
frame.setLayout(null);
frame.setResizable(false);
}
public static Color randomColor () {
Random rand = new Random();
int randomNum = rand.nextInt((4 - 1) + 1) + 1;
return switch (randomNum) {
case 1 -> red;
case 2 -> green;
case 3 -> blue;
case 4 -> yellow;
default -> null;
};
}
}```

2D JButton array, want to add actionlisteners to them for a game

I want to make an TIC TAC TOE Game but I have a problem.
I made a 2D array and I don't know how to address them to get the ActionListener working.
Here is my code:
public class GUI {
public static JButton[][] buttonsall = new JButton[3][3];
public static JFrame frame = new JFrame("TIC TAC TOE");
public static void draw() {
// frame
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setResizable(false);
frame.setBackground(Color.white);
frame.setBounds(500, 500, 600,600);
// actionListener
ActionListener listener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() instanceof JButton) {
//dont know further here
}
}
};
//buttons buttonsall[x][y]
for (int y = 0; y<3;y++) {
for (int x = 0; x<3;x++) {
buttonsall[x][y] = new JButton();
buttonsall[x][y].setVisible(true);
buttonsall[x][y].setSize(80, 80);
buttonsall[x][y].addActionListener(listener);
System.out.println(buttonsall[x][y] +" "+x +" "+y);
frame.add(buttonsall[x][y]);
buttonsall[x][y].setBackground(Color.white);
}
}
frame.setLayout(new GridLayout(3,3));
}
You could setName for each JButton while it is created. I update your code as below:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class GUI {
public static JButton[][] buttonsall = new JButton[3][3];
public static JFrame frame = new JFrame("TIC TAC TOE");
public static void draw() {
// frame
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setResizable(false);
frame.setBackground(Color.white);
frame.setBounds(500, 500, 600, 600);
// actionListener
ActionListener listener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() instanceof JButton) {
//dont know further here
JButton b = (JButton)e.getSource();
System.out.println("Button is:" + b.getName());
}
}
};
//buttons buttonsall[x][y]
for (int y = 0; y < 3; y++) {
for (int x = 0; x < 3; x++) {
buttonsall[x][y] = new JButton();
buttonsall[x][y].setVisible(true);
buttonsall[x][y].setName("Button_" + x + "_" + y);
buttonsall[x][y].setSize(80, 80);
buttonsall[x][y].addActionListener(listener);
System.out.println(buttonsall[x][y] + " " + x + " " + y);
frame.add(buttonsall[x][y]);
buttonsall[x][y].setBackground(Color.white);
}
}
frame.setLayout(new GridLayout(3, 3));
}
public static void main(String[] args) {
GUI.draw();
}
}
Your question is very similar to this question.
Essentially you want to use ActionEvent.getSource() and cast it to a JButton.
Then you can do whatever you want to the JButton (change the background color, change the text, etc.)
EDIT: I didn't realize that you wanted to get the x and y of the JButton.
public class TicTacToe {
public static TicTacToeButton[][] buttonsall = new TicTacToeButton[3][3];
public static JFrame frame = new JFrame("TIC TAC TOE");
public static void draw() {
// frame
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setResizable(false);
frame.setBackground(Color.white);
frame.setBounds(500, 500, 600,600);
// actionListener
ActionListener listener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source instanceof TicTacToeButton) {
TicTacToeButton btn = (TicTacToeButton) source;
int btnBoardX = btn.getBoardX();
int btnBoardY = btn.getBoardY();
// Go ahead and do what you like
}
}
};
//buttons buttonsall[x][y]
for (int y = 0; y<3;y++) {
for (int x = 0; x<3;x++) {
buttonsall[x][y] = new TicTacToeButton(x, y);
buttonsall[x][y].setVisible(true);
buttonsall[x][y].setSize(80, 80);
buttonsall[x][y].addActionListener(listener);
System.out.println(buttonsall[x][y] +" "+x +" "+y);
frame.add(buttonsall[x][y]);
buttonsall[x][y].setBackground(Color.white);
}
}
frame.setLayout(new GridLayout(3,3));
}
private static class TicTacToeButton extends JButton {
private int boardX;
private int boardY;
public TicTacToeButton(int boardX, int boardY) {
super();
this.boardX = boardX;
this.boardY = boardY;
}
public int getBoardX() {
return this.boardX;
}
public int getBoardY() {
return this.boardY;
}
}
}

Selected variables doesn't change on pong game - Swing

I'm trying to make a pong game by using Swing. I have a menu screen where you can change your preferences such as music, game speed and you can choose multiplayer options etc. But when I made a choice, their values don't change. I have my mainmenu class and computer class.
For ex: I want to change the difficulty which means changing the AI's speed but I wasn't be able to do it. I am looking forward for an answer, maybe it's so simple but I can't see it.
This is my code:
public class MenuPanel
{
ScoreBoard sc = new ScoreBoard();
private JFrame mainFrame;
private JFrame optionsFrame;
private JPanel menuPanel;
private JPanel optionsPanel;
private JFrame gameEndFrame;
private JPanel gameEndPanel;
JCheckBox twoPlayer;
// creating the swing components and containers,
// there are two frames to swap between them,
// we tried to use cardLayout but it didn't work for us.
public MenuPanel() {
mainFrame = new JFrame("Welcome To Pong Game");
mainFrame.setSize(700,700);
mainFrame.setLayout(new CardLayout());
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
menuPanel = new JPanel(null);
menuPanel.setSize(700,700);
menuPanel.setVisible(true);
mainFrame.add(menuPanel);
optionsFrame = new JFrame("Settings");
optionsFrame.setSize(700, 700);
optionsFrame.setLayout(new CardLayout());
optionsFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel optionsPanel = new JPanel(null) ;
optionsPanel.setSize(700,700);
optionsPanel.setVisible(true);
optionsFrame.add(optionsPanel);
// mainPanel components
ImageIcon ic1 = new ImageIcon("C:\\Users\\Onur17\\Downloads\\Actions-player-play-icon.png");
ImageIcon ic2 = new ImageIcon("C:\\Users\\Onur17\\Downloads\\Settings-L-icon.png");
ImageIcon ic3 = new ImageIcon("C:\\Users\\Onur17\\Downloads\\cup-icon.png");
ImageIcon ic4 = new ImageIcon("C:\\Users\\Onur17\\Downloads\\Button-Close-icon.png");
ImageIcon ic5 = new ImageIcon("C:\\Users\\Onur17\\Downloads\\ice-2025937_960_720.jpg");
ImageIcon ic6 = new ImageIcon("C:\\Users\\Onur17\\Downloads\\tenis1.png");
JLabel mainLabel = new JLabel();
Font font = new Font("Papyrus", Font.BOLD,26);
mainLabel.setFont(font);
mainLabel.setForeground(Color.RED);
mainLabel.setText("PONG GAME");
JButton startButton = new JButton("Start Game");
JButton optionsButton = new JButton("Options");
JButton leaderButton = new JButton("Leaderboard");
JButton exitButton = new JButton("Exit");
JButton icb1 = new JButton(ic1);
JButton icb2 = new JButton(ic2);
JButton icb3 = new JButton(ic3);
JButton icb4 = new JButton(ic4);
JButton icb6 = new JButton(ic6);
// at first, we tried to keep our buttons and labels in panels
// but then we didn't add an image to label as the background
// so we created a JLabel to set its image as the background, we may remove it later.
JLabel mn = new JLabel(ic5);
mn.setBackground(Color.BLUE);
mn.setBounds(1, 1, 700, 700);
Font font3 = new Font("Calibri", Font.PLAIN, 20);
twoPlayer = new JCheckBox();
twoPlayer.setFont(font3);
twoPlayer.setForeground(Color.DARK_GRAY);
twoPlayer.setText(" MultiPlayer");
twoPlayer.setBounds(200, 350, 220, 40);
menuPanel.add(mn);
mn.add(mainLabel);
mn.add(startButton);
mn.add(optionsButton);
mn.add(leaderButton);
mn.add(exitButton);
mn.add(icb1);
mn.add(icb2);
mn.add(icb3);
mn.add(icb4);
mn.add(icb6);
mn.add(twoPlayer);
mainFrame.setVisible(true);
// the components added by their coordinates to make them look formal
mainLabel.setBounds(210, 100, 220, 40);
startButton.setBounds(200, 150, 220, 40);
optionsButton.setBounds(200, 200, 220, 40);
leaderButton.setBounds(200, 250, 220, 40);
exitButton.setBounds(200, 300, 220, 40);
icb1.setBounds(150, 150, 40, 40);
icb2.setBounds(150, 200, 40, 40);
icb3.setBounds(150, 250, 40, 40);
icb4.setBounds(150, 300, 40, 40);
icb6.setBounds(150,350,40,40);
startButton.setBorder(BorderFactory.createRaisedBevelBorder());
optionsButton.setBorder(BorderFactory.createRaisedBevelBorder());
leaderButton.setBorder(BorderFactory.createRaisedBevelBorder());
exitButton.setBorder(BorderFactory.createRaisedBevelBorder());
// optionsPanel components
JButton doneButton = new JButton("Done");
doneButton.setBounds(150,330,220,40);
doneButton.setBorder(BorderFactory.createRaisedBevelBorder());
Font font1 = new Font("Calibri", Font.PLAIN,24);
Font font2 = new Font("Calibri", Font.BOLD,19);
JLabel st = new JLabel();
st.setFont(font1);
st.setForeground(Color.DARK_GRAY);
st.setText("-OPTIONS-");
JLabel difficulty = new JLabel("Difficulty: ");
difficulty.setFont(font2);
difficulty.setForeground(Color.DARK_GRAY);
JLabel music = new JLabel("Sound: ");
music.setFont(font2);
music.setForeground(Color.DARK_GRAY);
JLabel gSpeed = new JLabel("Game Speed: ");
gSpeed.setFont(font2);
gSpeed.setForeground(Color.DARK_GRAY);
JLabel screen = new JLabel(ic5);
screen.setBackground(Color.BLUE);
screen.setBounds(1, 1, 700, 700);
JRadioButton rb1 = new JRadioButton("Easy");
JRadioButton rb2 = new JRadioButton("Normal");
JRadioButton rb3 = new JRadioButton("Hard");
JRadioButton rb4 = new JRadioButton("On");
JRadioButton rb5 = new JRadioButton("Off");
JRadioButton rb6 = new JRadioButton("x");
JRadioButton rb7 = new JRadioButton("2x");
JRadioButton rb8 = new JRadioButton("3x");
ButtonGroup bg1 = new ButtonGroup();
ButtonGroup bg2 = new ButtonGroup();
ButtonGroup bg3 = new ButtonGroup();
bg1.add(rb1);
bg1.add(rb2);
bg1.add(rb3);
bg2.add(rb4);
bg2.add(rb5);
bg3.add(rb6);
bg3.add(rb7);
bg3.add(rb8);
optionsPanel.add(screen);
screen.add(difficulty);
screen.add(st);
screen.add(gSpeed);
screen.add(rb1);
screen.add(rb2);
screen.add(rb3);
screen.add(rb4);
screen.add(rb5);
screen.add(rb6);
screen.add(rb7);
screen.add(rb8);
screen.add(music);
screen.add(doneButton);
st.setBounds(200,100,220,40);
difficulty.setBounds(100,150,90,40);
music.setBounds(100,200,90,40);
gSpeed.setBounds(100, 250, 120, 40);
rb1.setBounds(200,150,60,40);
rb2.setBounds(260,150,80,40);
rb3.setBounds(340, 150, 60, 40);
rb4.setBounds(200, 200, 50, 40);
rb5.setBounds(250,200,50,40);
rb6.setBounds(220, 250, 50, 40);
rb7.setBounds(270, 250, 50, 40);
rb8.setBounds(320, 250, 50, 40);
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Pong pong = new Pong();
sound("Marimba-music");
mainFrame.dispose();
if(twoPlayer.isSelected()) {
pong.c.isTwoPlayer = true;
}
else {
pong.c.isTwoPlayer = false;
}
}
});
optionsButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
mainFrame.setVisible(false);
optionsFrame.setVisible(true);
}
});
doneButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
optionsFrame.dispose();
Pong pong = new Pong();
if(rb1.isSelected())
{
pong.c.setUp(-10);;
pong.c.setDown(10);
}
else if(rb2.isSelected())
{
pong.c.setUp(-11);
pong.c.setDown(11);
}
else if(rb3.isSelected())
{
pong.c.setUp(-30);
pong.c.setDown(30);
}
if(rb4.isSelected())
{
sound("Marimba-music");
}
else if(rb5.isSelected())
{
soundStop("Marimba-music");
}
if(rb6.isSelected())
{
GamePanel g = new GamePanel();
g.x = 50;
}
else if(rb7.isSelected())
{
GamePanel g = new GamePanel();
g.x = 75;
}
else if(rb8.isSelected())
{
GamePanel g = new GamePanel();
g.x = 100;
System.out.println(g.x);
}
}
});
exitButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
mainFrame.dispose();
}
});
}
public void sound(String nm)
{
AudioStream BGM;
try {
InputStream test = new FileInputStream("./" +nm+".wav");
BGM = new AudioStream(test);
AudioPlayer.player.start(BGM);
}
catch(IOException error) {
JOptionPane.showMessageDialog(null, error.getMessage());
}
}
public void soundStop(String nm)
{
AudioStream BGM;
try {
InputStream test = new FileInputStream("./" +nm+".wav");
BGM = new AudioStream(test);
AudioPlayer.player.stop(BGM);
}
catch(IOException error) {
JOptionPane.showMessageDialog(null, error.getMessage());
}
}
}
My Computer.class:
public class Computer
{
private GamePanel field;
private int y = Pong.WINDOW_HEIGHT / 2;
private int yCh = 0;
private int up = -10;
private int down = 10;
private int width = 20;
private int height = 90;
boolean isTwoPlayer = false;
public Computer() {
}
public void update(Ball b) {
if(y + height > Pong.WINDOW_HEIGHT)
{
y = Pong.WINDOW_HEIGHT - height;
}
else if(y < 0)
{
y = 0;
}
if(!isTwoPlayer) {
if(b.getY() < y+height && y >= 0)
{
yCh = up;
}
else if(b.getY() > y && y + height <= Pong.WINDOW_HEIGHT)
{
yCh = down;
}
y = y + yCh;
}
else {
y = y + yCh;
}
}
public void setYPosition(int speed) {
yCh = speed;
}
public void paint(Graphics g) {
g.setColor(Color.BLACK);
g.fillRoundRect(450, y, width, height, 10, 10);
}
public int getX() {
return 450;
}
public int getY() {
return y;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public int getUp() {
return up;
}
public int getDown() {
return down;
}
public void setUp(int up) {
this.up = up;
}
public void setDown(int down) {
this.down = down;
}
I don't know how your whole program is structured. But in this piece of code:
doneButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
optionsFrame.dispose();
Pong pong = new Pong();
You create a new instance of Pong class and set the values of the new created instance.
This instance is not used anywhere else. You may need to use a instance of Pong that is already in use, or make other classes use the new created instance.

Java GUI repainting error?

This one's a tough one - I have a JFrame that generates JTextFields. When I go from generating 2 JTextFields to 12 JTextfields (for example), I see some error where there is an extra differently-sized JTextField at the end. It seems to be a repaint error.
Main.java code:
import java.awt.*;
import javax.swing.*;
public class Main {
public static Display display = new Display();
public static void main(String[] args) {
display.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
display.setVisible(true);
}
}
Display.java code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Display extends JFrame {
final int FRAME_WIDTH = 820;
final int FRAME_HEIGHT = 700;
final int X_OFFSET = 40;
final int Y_OFFSET = 40;
final int GRAPH_OFFSETX = 35;
final int GRAPH_OFFSETY = 60;
final int GRAPH_WIDTH = 500;
final int GRAPH_HEIGHT = 500;
final int GRAPH_INTERVAL = 20;
JButton submit;
JTextField top;
JTextField bottom;
JTextField numPoint;
JPanel bpanel;
JPanel points;
int maxPoints;
public Display() {
init();
}
public void init() {
setBackground(Color.WHITE);
setLocation(X_OFFSET, Y_OFFSET);
setSize(FRAME_WIDTH, FRAME_HEIGHT);
setTitle("Geometric Transformations");
getContentPane().setLayout(null);
setDefaultLookAndFeelDecorated(true);
top = new JTextField(); // parameter is size of input characters
top.setText("1 2 3");
top.setBounds(590, 150, 120, 25);
bottom = new JTextField(); // parameter is size of input characters
bottom.setText("5 6 7");
bottom.setBounds(590, 200, 120, 25);
numPoint = new JTextField();
numPoint.setText("Number of Points?");
numPoint.setBounds(550,200,200,25);
this.add(numPoint);
SubmitButton submit = new SubmitButton("Submit");
submit.setBounds(570, 250, 170, 25);
bpanel = new JPanel(new GridLayout(2,3));
bpanel.add(top);
bpanel.add(bottom);
bpanel.add(submit);
points = new JPanel(new GridLayout(2,2));
points.setBounds(540,250,265,60);
this.add(points);
bpanel.setBounds(550,100,200,70);
this.add(bpanel, BorderLayout.LINE_START);
Component[] a = points.getComponents();
System.out.println(a.length);
repaint();
}
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.WHITE);
g.fillRect(100, 100, 20, 30);
g.setColor(Color.BLACK);
genGraph(g, GRAPH_OFFSETX, GRAPH_OFFSETY, GRAPH_WIDTH, GRAPH_HEIGHT, GRAPH_INTERVAL);
}
public void genGraph (Graphics g, int x, int y, int width, int height, int interval) {
// draw background
int border = 5;
g.setColor(Color.BLACK);
width = width - (width % interval);
height = height - (height % interval);
for (int col=x; col <= x+width; col+=interval) {
g.drawLine(col, y, col, y+height);
}
for (int row=y; row <= y+height; row+=interval) {
g.drawLine(x, row, x+width, row);
}
}
class SubmitButton extends JButton implements ActionListener {
public SubmitButton(String title){
super(title);
addActionListener(this);
this.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
maxPoints = Integer.parseInt(numPoint.getText()) * 2;
points.removeAll();
for (int i=0; i<maxPoints; i++) {
JTextField textField = new JTextField();
points.add(textField);
}
points.validate(); // necessary when adding components to a JPanel
// http://stackoverflow.com/questions/369823/java-gui-repaint-problem-solved
// What to Check:
// Things between commas are either spaces (which will be stripped later)
// or numbers!
// Pairs must match up!
}
}
}
The new components are redrawn over the previous ones.
I added points.repaint(); after points.validate(); and the problem was gone.
Note: I was annoyed with the issue of repainting of the grid too (put the window in front then back, you will see).
From a quick search, it seems better to avoid painting directly on the JFrame, but instead delegate that to a sub-component. If I am wrong, somebody tell me.
Here is my solution (imperfect, I leave to you the task to improve it... :-P
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SODisplay extends JFrame {
final int FRAME_WIDTH = 820;
final int FRAME_HEIGHT = 700;
final int X_OFFSET = 40;
final int Y_OFFSET = 40;
JButton submit;
JTextField top;
JTextField bottom;
JTextField numPoint;
JPanel bpanel;
JPanel points;
GridPanel grid;
int maxPoints;
public SODisplay() {
init();
}
public void init() {
setBackground(Color.WHITE);
setLocation(X_OFFSET, Y_OFFSET);
setSize(FRAME_WIDTH, FRAME_HEIGHT);
setTitle("Geometric Transformations");
getContentPane().setLayout(null);
setDefaultLookAndFeelDecorated(true);
grid = new GridPanel();
grid.setBounds(0,0,530,FRAME_HEIGHT);
this.add(grid);
top = new JTextField(); // parameter is size of input characters
top.setText("1 2 3");
top.setBounds(590, 150, 120, 25);
bottom = new JTextField(); // parameter is size of input characters
bottom.setText("5 6 7");
bottom.setBounds(590, 200, 120, 25);
numPoint = new JTextField();
numPoint.setText("Number of Points?");
numPoint.setBounds(550,200,200,25);
this.add(numPoint);
SubmitButton submit = new SubmitButton("Submit");
submit.setBounds(570, 250, 170, 25);
bpanel = new JPanel(new GridLayout(2,3));
bpanel.add(top);
bpanel.add(bottom);
bpanel.add(submit);
points = new JPanel(new GridLayout(2,2));
points.setBounds(540,250,265,60);
this.add(points);
bpanel.setBounds(550,100,200,70);
this.add(bpanel, BorderLayout.LINE_START);
Component[] a = points.getComponents();
System.out.println(a.length);
repaint();
}
class SubmitButton extends JButton implements ActionListener {
public SubmitButton(String title){
super(title);
addActionListener(this);
this.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
maxPoints = Integer.parseInt(numPoint.getText()) * 2;
points.removeAll();
for (int i=0; i<maxPoints; i++) {
JTextField textField = new JTextField();
points.add(textField);
}
points.validate(); // necessary when adding components to a JPanel
points.repaint();
// http://stackoverflow.com/questions/369823/java-gui-repaint-problem-solved
// What to Check:
// Things between commas are either spaces (which will be stripped later)
// or numbers!
// Pairs must match up!
}
}
public static void main(String[] args) {
// Schedule a job for the event-dispatching thread:
// creating and showing this application's GUI.
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
SODisplay display = new SODisplay();
display.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
display.setVisible(true);
}
});
}
class GridPanel extends JPanel {
// Or drop the offset and adjust the placement of the component
final int GRAPH_OFFSETX = 35;
final int GRAPH_OFFSETY = 60;
final int GRAPH_WIDTH = 500;
final int GRAPH_HEIGHT = 500;
final int GRAPH_INTERVAL = 20;
public GridPanel() {
}
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.WHITE);
g.fillRect(100, 100, 20, 30);
g.setColor(Color.BLACK);
genGraph(g, GRAPH_OFFSETX, GRAPH_OFFSETY, GRAPH_WIDTH, GRAPH_HEIGHT, GRAPH_INTERVAL);
}
public void genGraph (Graphics g, int x, int y, int width, int height, int interval) {
// draw background
int border = 5;
g.setColor(Color.BLACK);
width = width - (width % interval);
height = height - (height % interval);
for (int col=x; col <= x+width; col+=interval) {
g.drawLine(col, y, col, y+height);
}
for (int row=y; row <= y+height; row+=interval) {
g.drawLine(x, row, x+width, row);
}
}
}
}
That's just my test code in one file for simplicity, you might want to dissect it differently, of course.

Categories

Resources