I have added a while loop that will change between players as seen in the code below. Before I add this while loop it displays the grid, buttons, etc but when I add this loop the panel is just plain white. I have no idea why.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.security.auth.x500.X500Principal;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import org.omg.CORBA.PRIVATE_MEMBER;
public class Game
{
boolean p1;
private int counterY1 = 515, counterY2 = 515, counterY3 = 515, counterY4 = 515;
boolean playerTurn = true;
boolean playerTurn2 = false;
boolean moveLoop = true;
public void moveC1Up()
{
counterY1 -= 51 * diceRoll();
}
public void moveC2Up()
{
counterY2 -= 51 * diceRoll();
}
public void moveC3Up()
{
counterY3 -= 51 * diceRoll();
}
public void moveC4Up()
{
counterY4 -= 51 * diceRoll();
}
public int diceRoll()
{
int randGen = (int)(Math.random()*1) + 1;
System.out.print(randGen);
return randGen;
}
private JButton moveC1But, moveC2But, rollDiceButton;
private JLabel amountRolledLabel;
public Game()
{
JFrame window = new JFrame ("Main Game");
final JPanel firstPanel = new JPanel(new GridLayout(3,1))
{
public void paintComponent(Graphics g)
{
Graphics2D g2d = (Graphics2D) g;
super.paintComponent(g2d);
int width = getWidth() / 3;
int height = getHeight() / 11;
for (int i = 0; i < 4; i++) {
g.drawLine(i * width, 0, i * width, getHeight());
}
for (int i = 0; i < 11; i++) {
g.drawLine(0, i * height, getWidth(), i * height);
}
g.setColor(Color.DARK_GRAY);
g.drawOval(220, counterY1, 40, 40);
g.fillOval(220, counterY1, 40, 40);
g.drawOval(300, counterY2, 40, 40);
g.fillOval(300, counterY2, 40, 40);
g.setColor(Color.LIGHT_GRAY);
g.drawOval(410, counterY3, 40, 40);
g.fillOval(410, counterY3, 40, 40);
g.drawOval(490, counterY4, 40, 40);
g.fillOval(490, counterY4, 40, 40);
}
};
JPanel mainPanel = new JPanel(new BorderLayout());
mainPanel.add(firstPanel, BorderLayout.CENTER);
JPanel rightSidePanel = new JPanel(new GridLayout(10,1));
moveC1But = new JButton("Move Counter 1");
moveC2But = new JButton("Move Counter 2");
rollDiceButton = new JButton("Roll Dice");
rightSidePanel.add(moveC1But, BorderLayout.LINE_START);
rightSidePanel.add(moveC2But, BorderLayout.LINE_END);
rightSidePanel.add(rollDiceButton, BorderLayout.SOUTH);
mainPanel.add(rightSidePanel, BorderLayout.EAST);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.getContentPane().add(mainPanel);
window.setSize(700, 600);
window.setLocationRelativeTo(null);
window.setVisible(true);
window.setResizable(false);
while(moveLoop == true)
{
moveC1But.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae)
{
diceRoll();
moveC1Up();
firstPanel.repaint();
System.out.print(diceRoll());
System.out.print("Test1");
playerTurn = false;
playerTurn2 = true;
moveLoop = false;
}
});
moveC2But.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae)
{
diceRoll();
moveC3Up();
firstPanel.repaint();
System.out.print(diceRoll());
System.out.print("Test1");
playerTurn = false;
playerTurn2 = true;
moveLoop = false;
}
});
}
}
public static void main(String args[])
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
new Game();
}
});
}
}
EDIT:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.security.auth.x500.X500Principal;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import org.omg.CORBA.PRIVATE_MEMBER;
public class Game
{
boolean p1;
private int counterY1 = 515, counterY2 = 515, counterY3 = 515, counterY4 = 515;
boolean playerTurn = true;
boolean playerTurn2 = false;
boolean moveLoop = true;
public void moveC1Up()
{
counterY1 -= 51 * diceRoll();
}
public void moveC2Up()
{
counterY2 -= 51 * diceRoll();
}
public void moveC3Up()
{
counterY3 -= 51 * diceRoll();
}
public void moveC4Up()
{
counterY4 -= 51 * diceRoll();
}
public int diceRoll()
{
int randGen = (int)(Math.random()*1) + 1;
System.out.print(randGen);
return randGen;
}
private JButton moveC1But, moveC2But, rollDiceButton;
private JLabel amountRolledLabel;
public Game()
{
JFrame window = new JFrame ("Main Game");
final JPanel firstPanel = new JPanel(new GridLayout(3,1))
{
public void paintComponent(Graphics g)
{
Graphics2D g2d = (Graphics2D) g;
super.paintComponent(g2d);
int width = getWidth() / 3;
int height = getHeight() / 11;
for (int i = 0; i < 4; i++) {
g.drawLine(i * width, 0, i * width, getHeight());
}
for (int i = 0; i < 11; i++) {
g.drawLine(0, i * height, getWidth(), i * height);
}
g.setColor(Color.DARK_GRAY);
g.drawOval(220, counterY1, 40, 40);
g.fillOval(220, counterY1, 40, 40);
g.drawOval(300, counterY2, 40, 40);
g.fillOval(300, counterY2, 40, 40);
g.setColor(Color.LIGHT_GRAY);
g.drawOval(410, counterY3, 40, 40);
g.fillOval(410, counterY3, 40, 40);
g.drawOval(490, counterY4, 40, 40);
g.fillOval(490, counterY4, 40, 40);
}
};
JPanel mainPanel = new JPanel(new BorderLayout());
mainPanel.add(firstPanel, BorderLayout.CENTER);
JPanel rightSidePanel = new JPanel(new GridLayout(10,1));
moveC1But = new JButton("Move Counter 1");
moveC2But = new JButton("Move Counter 2");
rollDiceButton = new JButton("Roll Dice");
rightSidePanel.add(moveC1But, BorderLayout.LINE_START);
rightSidePanel.add(moveC2But, BorderLayout.LINE_END);
rightSidePanel.add(rollDiceButton, BorderLayout.SOUTH);
mainPanel.add(rightSidePanel, BorderLayout.EAST);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.getContentPane().add(mainPanel);
window.setSize(700, 600);
window.setLocationRelativeTo(null);
window.setVisible(true);
window.setResizable(false);
if(playerTurn == true)
{
moveC1But.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae)
{
diceRoll();
moveC1Up();
firstPanel.repaint();
System.out.print(diceRoll());
System.out.print("Test1");
playerTurn = false;
playerTurn2 = true;
moveLoop = false;
}
});
moveC2But.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae)
{
diceRoll();
moveC2Up();
firstPanel.repaint();
System.out.print(diceRoll());
System.out.print("Test1");
playerTurn = false;
playerTurn2 = true;
moveLoop = false;
}
});
}else if (playerTurn2 == true)
{
moveC1But.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae)
{
diceRoll();
moveC3Up();
firstPanel.repaint();
System.out.print(diceRoll());
System.out.print("Test1");
playerTurn = false;
playerTurn2 = true;
moveLoop = false;
}
});
moveC2But.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae)
{
diceRoll();
moveC4Up();
firstPanel.repaint();
System.out.print(diceRoll());
System.out.print("Test1");
playerTurn = false;
playerTurn2 = true;
moveLoop = false;
}
});
}
}
public static void main(String args[])
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
new Game();
}
});
}
Yours is a common problem: you've got a long-running bit of code that is running on the Swing event thread, completely tying it up. Since this thread is responsible for all of Swing drawing and user interaction, your GUI becomes essentially frozen until the long-running code finishes. Possible solutions include:
Use a Swing Timer for your game loop, avoiding the use of while (true) on the Swing event thread.
Use a background thread for a long-running bit of code. This can be conveniently be done with a SwingWorker.
Do neither. Having a look at your code, I see no reason to have the while (true) loop in the first place. All it does is to add ActionListeners to JButtons multiple times and thus is completely worthless. So get rid of it and add the ActionListeners only once. For your code, this is your best option -- rethink your code so that it makes more sense.
Edit
You ask:
Yes I see what the ifs are doing and have removed them. But basically I have two buttons, move counter 1 and move counter 2 each player has 2 counters, but only the two buttons. I want player 1 to start and hit which counter they would like to move, this then allows the second player to move their counter and visa versa.
The logic must be inside your ActionListener. For example:
moveC1But.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
diceRoll();
if (player1Turn) {
// logic for player turn 1
} else {
// logic for player turn 2
}
}
});
In your current code the loop doesn't let the JFrame to call repaint(); because it is never broken until the user clicks a button, which is impossible if the JFrame can't draw the components.
Here's how you should do your inputs instead.
package beaudoin.apps;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import sun.awt.RepaintArea;
public class Game {
boolean p1;
private int counterY1 = 515, counterY2 = 515, counterY3 = 515, counterY4 = 515;
boolean playerTurn = true;
boolean playerTurn2 = false;
public void moveC1Up() {
counterY1 -= 51 * diceRoll();
}
public void moveC2Up() {
counterY2 -= 51 * diceRoll();
}
public void moveC3Up() {
counterY3 -= 51 * diceRoll();
}
public void moveC4Up() {
counterY4 -= 51 * diceRoll();
}
public int diceRoll() {
int randGen = (int) (Math.random() * 1) + 1;
System.out.print(randGen);
return randGen;
}
private JButton moveC1But, moveC2But, rollDiceButton;
private JLabel amountRolledLabel;
public Game() {
JFrame window = new JFrame("Main Game");
final JPanel firstPanel = new JPanel(new GridLayout(3, 1)) {
private static final long serialVersionUID = -1729570833533906839L;
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
super.paintComponent(g2d);
int width = getWidth() / 3;
int height = getHeight() / 11;
for (int i = 0; i < 4; i++) {
g.drawLine(i * width, 0, i * width, getHeight());
}
for (int i = 0; i < 11; i++) {
g.drawLine(0, i * height, getWidth(), i * height);
}
g.setColor(Color.DARK_GRAY);
g.drawOval(220, counterY1, 40, 40);
g.fillOval(220, counterY1, 40, 40);
g.drawOval(300, counterY2, 40, 40);
g.fillOval(300, counterY2, 40, 40);
g.setColor(Color.LIGHT_GRAY);
g.drawOval(410, counterY3, 40, 40);
g.fillOval(410, counterY3, 40, 40);
g.drawOval(490, counterY4, 40, 40);
g.fillOval(490, counterY4, 40, 40);
}
};
JPanel mainPanel = new JPanel(new BorderLayout());
mainPanel.add(firstPanel, BorderLayout.CENTER);
JPanel rightSidePanel = new JPanel(new GridLayout(10, 1));
moveC1But = new JButton("Move Counter 1");
moveC1But.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
diceRoll();
moveC1Up();
firstPanel.repaint();
playerTurn = false;
playerTurn2 = true;
}
});
moveC2But = new JButton("Move Counter 2");
moveC2But.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
diceRoll();
moveC3Up();
firstPanel.repaint();
playerTurn = false;
playerTurn2 = true;
}
});
rollDiceButton = new JButton("Roll Dice");
rightSidePanel.add(moveC1But, BorderLayout.LINE_START);
rightSidePanel.add(moveC2But, BorderLayout.LINE_END);
rightSidePanel.add(rollDiceButton, BorderLayout.SOUTH);
mainPanel.add(rightSidePanel, BorderLayout.EAST);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.getContentPane().add(mainPanel);
window.setSize(700, 600);
window.setLocationRelativeTo(null);
window.setVisible(true);
window.setResizable(false);
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Game();
}
});
}
}
Related
Hi I would like to have the following user interface:
And when the user clicks on start, I would like to add dynamically a JPanel underneath these elements. Something like this:
I am able to generate the grid in an empty JFrame, but when I try to add it when there are more elements inside the JFrame it appears, but very small.
This is the code that I have tried. The class UITable creates the buttons and input text
public UITable(){
jfrm = new JFrame("Plants experiment");
jfrm.setLayout(new FlowLayout());
jfrm.setSize(1000, 1000);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//JLabel titles for input texts
JLabel jlab_plants = new JLabel(" Enter nÂș plants: ");
JLabel jlab_time = new JLabel(" Enter evolution time: ");
jlab_prueba = new JLabel("");
//Input texts
jtf_plants = new JTextField(10);
jtf_plants.setActionCommand("numPlants");
jtf_time = new JTextField(10);
jtf_time.setActionCommand("time");
//Buttons
jbtnStart = new JButton("Start");
//Add components
jfrm.add(jlab_plants);
jfrm.add(jtf_plants);
jfrm.add(jlab_time);
jfrm.add(jtf_time);
jfrm.add(jbtnStart);
jfrm.add(jlab_prueba);
//Set visibility
jfrm.setVisible(true);
}
Adding dynamically the grid:
#Override
public void actionPerformed(ActionEvent ae) {
// ...
this.view.jfrm.add(new Grid());
this.view.jfrm.revalidate();
this.view.jfrm.repaint();
}
This is the Grid class:
public class Grid extends JPanel{
//Change Point to Plant in order to have a different color for each object
private List<Plant> fillCells;
public Grid() {
//fillCells = new ArrayList<>(25);
fillCells = PlantsControler.myPlants;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println("Width: "+getWidth()+" Height: "+ getHeight());
---- //Returns Width: 10 Height: 10 ------
g.clearRect(0, 0, getWidth(), getHeight());
for (Plant fillCell : fillCells) {
int cellX = 10 + (fillCell.getX() * 10);
int cellY = 10 + (fillCell.getY() * 10);
g.setColor(fillCell.getColor());
g.fillRect(cellX, cellY, 10, 10);
}
g.setColor(Color.BLACK);
g.drawRect(10, 10, 800, 500);
for (int i = 10; i <= 800; i += 10) {
g.drawLine(i, 10, i, 510);
}
for (int i = 10; i <= 500; i += 10) {
g.drawLine(10, i, 810, i);
}
}
public void fillCell(int x, int y, Color color) {
fillCells.add(new Plant(x, y, color));
repaint();
}
public void fillCell(Plant plant){
fillCells.add(plant);
repaint();
}
public void fillCell(){
repaint();
}
public void clearGrid(){
fillCells.clear();
}
Thanks in advance!!!
You can try something like below.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class DemoFrame extends JFrame {
JTextField field = new JTextField();
public DemoFrame() {
setLayout(new BorderLayout());
JPanel controlsPane = new JPanel(new FlowLayout());
controlsPane.add(new JLabel("I m a Label"));
field.setPreferredSize(new Dimension(100,20));
controlsPane.add(field);
JButton button = new JButton("I am add drawPanel");
controlsPane.add(button);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent paramActionEvent) {
DemoFrame.this.add(new DrawPanel(), BorderLayout.CENTER);
DemoFrame.this.revalidate();
}
});
add(controlsPane,BorderLayout.NORTH);
}
public static void main(String[] args) {
DemoFrame frame = new DemoFrame();
frame.setVisible(true);
frame.pack();
}
class DrawPanel extends JPanel {
#Override
protected void paintComponent(Graphics g) {
// TODO Auto-generated method stub
super.paintComponent(g);
g.setColor(Color.BLUE);
g.drawString(field.getText(), this.getWidth()/2, this.getHeight()/2);
}
}
}
I have this code and I want the user to be able to restart the game by pressing R, but I do not know how to do this, I've tried to call the main method again, which obviously didn't work, but I don't know any other way to restart it, this is the main class code:
import javax.swing.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
public class Main extends JPanel implements KeyListener {
long startT = System.currentTimeMillis();
long elapsedTimeMillis;
float elapsedT;
private Player player;
private Stage stage;
private boolean isGameOver = false;
private EnemyManager manager;
public Main() {
setSize(800,600);
setPreferredSize(new Dimension(800,600));
setFocusable(true);
addKeyListener(this);
stage = new Stage();
player = new Player(this, 200, 500);
manager = new EnemyManager(this, 10);
}
#Override
public void update(Graphics g){
paint(g);
}
public void paint(Graphics g){
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
if(!isGameOver){
player.draw(g);
manager.draw(g);
stage.draw(g);
long elapsedTimeMillis = System.currentTimeMillis() - startT;
elapsedT = elapsedTimeMillis/1000F;
g.setColor(Color.white);
g.setFont(new Font("Century Gothic", Font.BOLD, 24));
g.drawString("You're alive for: " + elapsedT, 400, 50);
}else {
g.setFont(new Font("Century Gothic", Font.BOLD, 55));
g.setColor(Color.RED);
g.drawString("Game Over" , 250, 150);
g.setColor(Color.ORANGE);
g.setFont(new Font("Century Gothic", Font.BOLD, 24));
g.drawString("You lasted for: ", 300, 250);
g.drawString("Press to restart", 300, 300);
g.setColor(Color.white);
g.drawString("" + elapsedT, 480, 250);
g.drawString("R", 364, 300);
}
g.dispose();
repaint();
}
#Override
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
if (code == KeyEvent.VK_W){
}
if (code == KeyEvent.VK_A){
player.setdirectionX(-1);
}
if (code == KeyEvent.VK_S){
}
if (code == KeyEvent.VK_D){
player.setdirectionX(1);
}
if (code == KeyEvent.VK_R){
}
}
public void setGameOver(boolean flag){
isGameOver = flag;
}
#Override
public void keyReleased(KeyEvent e){
player.setdirectionX(0);
player.setdirectionY(0);
}
#Override
public void keyTyped(KeyEvent e) {
}
public Stage getStage(){
return stage;
}
public EnemyManager getEnemyManager(){
return manager;
}
public static void main(String[] args){
JFrame frame = new JFrame();
frame.setTitle("Dodge the bloody rectangles");
frame.add(new Main());
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(new Dimension(800,600));
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
public void restart() {
stage = new Stage();
player = new Player(this, 200, 500);
manager = new EnemyManager(this, 10);
isGameOver = false;
}
...
#Override
public void keyPressed(KeyEvent e) {
...
if (code == KeyEvent.VK_R){
restart();
}
}
I'm looking for a way to place a JComponent that uses Graphics alongside other JComponents such as JRadioButton.
Therefore, I tried to build a GridBagConstraints in my JPanel to allow easy placement. But I can't figure out how to place the graphic component on the grid using a correct constraint. If I add the constraint, a very small portion of the graphic appears.
My code below:
public class Interface extends JFrame{
private Visualization v;
private GridBagConstraints constraints=new GridBagConstraints();
private JRadioButton temperature,pluviometry;
public Interface(Visualization v){
this.setTitle("Pluviometry Data Viewer");
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.v=v;
//this.getContentPane().add(v);
//this.getContentPane().setLayout(new GridBagLayout());
constraints.gridx=0;
constraints.gridy=0;
constraints.gridheight=(int)v.getPreferredSize().getSize().getHeight();
constraints.gridwidth=(int)v.getPreferredSize().getSize().getWidth();
//constraints.fill=BOTH;
this.add(v);
//this.add(new JRadioButton("Temperature", true),constraints);
this.setVisible(true);
this.pack();
this.setSize(new Dimension(540, 360));
}
}
public class Visualization extends JComponent {
Data data;
private int y_axis=210;
private int x_axis=450;
public Visualization(Data d){
this.data=d;
}
#Override
public void paintComponent(Graphics g){
int width=getWidth();
int height=getHeight();
g.setColor(new Color(255, 78, 23));
g.drawLine(50, 20, 50, 230);
g.drawLine(50, 230, 500, 230);
for(int i=100;i<=500;i+=50){
g.drawLine(i, 230, i, 240);
}
for(int i=180;i>0;i-=40){
g.drawLine(50, i, 40, i);
}
}
#Override
public Dimension getPreferredSize(){
return new Dimension(200,100);
}
}
Thanks.
There are a number of small issues...
You never actually use a GridBagLayout
You never supply the GridBagConstraints to the container when you add the Visualization
The preferredSize of Visualization doesn't match what you are actually rendering
You should try and call setVisible last, once you've established the UI
Calling setSize on a JFrame isn't highly recommended
gridwidth and gridheight are measured in cells within the context of the GridBagLayout, not pixels...
For example...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JComponent;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JRadioButton;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestGUI extends JFrame {
private Visualization v;
private GridBagConstraints constraints = new GridBagConstraints();
private JRadioButton temperature, pluviometry;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
Visualization v = new Visualization();
TestGUI frame = new TestGUI(v);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
});
}
public TestGUI(Visualization v) {
this.setTitle("Pluviometry Data Viewer");
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.v = v;
setLayout(new GridBagLayout());
constraints.gridx = 0;
constraints.gridy = 0;
constraints.anchor = GridBagConstraints.NORTHWEST;
add(new JRadioButton("Cool stuff"), constraints);
constraints.gridx = 1;
constraints.gridy = 0;
constraints.fill=GridBagConstraints.BOTH;
this.add(v, constraints);
//this.add(new JRadioButton("Temperature", true),constraints);
this.pack();
this.setVisible(true);
}
public static class Visualization extends JComponent {
private int y_axis = 210;
private int x_axis = 450;
public Visualization() {
}
#Override
public void paintComponent(Graphics g) {
int width = getWidth();
int height = getHeight();
g.setColor(new Color(255, 78, 23));
g.drawLine(50, 20, 50, 230);
g.drawLine(50, 230, 500, 230);
for (int i = 100; i <= 500; i += 50) {
g.drawLine(i, 230, i, 240);
}
for (int i = 180; i > 0; i -= 40) {
g.drawLine(50, i, 40, i);
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(500 + 50, 230 + 50);
}
}
}
When creating the While and IF loops in the code below it creates an error saying: Unreachable code and suggesting that I remove the below code. I do not understand the issue here and I have tried moving the while statement with the code below the rest of the code inside the Main() method, but then my JFrame just appears white. Any help?
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.security.auth.x500.X500Principal;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import org.omg.CORBA.PRIVATE_MEMBER;
public class Game
{
boolean p1;
private int counterY1 = 515, counterY2 = 515, counterY3 = 515, counterY4 = 515;
boolean playerTurn = true;
boolean playerTurn2 = false;
boolean moveLoop = true;
public void moveC1Up()
{
counterY1 -= 51 * diceRoll();
}
public void moveC2Up()
{
counterY2 -= 51 * diceRoll();
}
public void moveC3Up()
{
counterY3 -= 51 * diceRoll();
}
public void moveC4Up()
{
counterY4 -= 51 * diceRoll();
}
public int diceRoll()
{
int randGen = (int)(Math.random()*1) + 1;
System.out.print(randGen);
return randGen;
}
private JButton moveC1But, moveC2But, rollDiceButton;
private JLabel amountRolledLabel;
public Game()
{
JFrame window = new JFrame ("Main Game");
final JPanel firstPanel = new JPanel(new GridLayout(3,1))
{
public void paintComponent(Graphics g)
{
Graphics2D g2d = (Graphics2D) g;
super.paintComponent(g2d);
int width = getWidth() / 3;
int height = getHeight() / 11;
for (int i = 0; i < 4; i++) {
g.drawLine(i * width, 0, i * width, getHeight());
}
for (int i = 0; i < 11; i++) {
g.drawLine(0, i * height, getWidth(), i * height);
}
g.setColor(Color.DARK_GRAY);
g.drawOval(220, counterY1, 40, 40);
g.fillOval(220, counterY1, 40, 40);
g.drawOval(300, counterY2, 40, 40);
g.fillOval(300, counterY2, 40, 40);
g.setColor(Color.LIGHT_GRAY);
g.drawOval(410, counterY3, 40, 40);
g.fillOval(410, counterY3, 40, 40);
g.drawOval(490, counterY4, 40, 40);
g.fillOval(490, counterY4, 40, 40);
}
};
JPanel mainPanel = new JPanel(new BorderLayout());
mainPanel.add(firstPanel, BorderLayout.CENTER);
JPanel rightSidePanel = new JPanel(new GridLayout(10,1));
moveC1But = new JButton("Move Counter 1");
moveC2But = new JButton("Move Counter 2");
rollDiceButton = new JButton("Roll Dice");
rightSidePanel.add(moveC1But, BorderLayout.LINE_START);
rightSidePanel.add(moveC2But, BorderLayout.LINE_END);
rightSidePanel.add(rollDiceButton, BorderLayout.SOUTH);
mainPanel.add(rightSidePanel, BorderLayout.EAST);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.getContentPane().add(mainPanel);
window.setSize(700, 600);
window.setLocationRelativeTo(null);
window.setVisible(true);
window.setResizable(false);
while(moveLoop == true)
{
moveC1But.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae)
{
diceRoll();
moveC1Up();
firstPanel.repaint();
System.out.print(diceRoll());
System.out.print("Test1");
playerTurn = false;
playerTurn2 = true;
moveLoop = false;
}
});
moveC2But.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae)
{
diceRoll();
moveC3Up();
firstPanel.repaint();
System.out.print(diceRoll());
System.out.print("Test1");
playerTurn = false;
playerTurn2 = true;
moveLoop = false;
}
});
}
}
public static void main(String args[])
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
new Game();
}
});
}
}
while(true) will continue forever as you have no break statements anywhere to leave the loop. That then means that all code below the loop can never be executed.
Because there is no break statement to break the infinite loop.
That's why compile shows you error Unreachable code because code below while(true) is never reached.
In your current code the loop doesn't let the JFrame to call repaint(); because it is never broken until the user clicks a button, which is impossible if the JFrame didn't yet draw the components.
Here's how you should do your inputs instead.
package beaudoin.apps;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import sun.awt.RepaintArea;
public class Game {
boolean p1;
private int counterY1 = 515, counterY2 = 515, counterY3 = 515, counterY4 = 515;
boolean playerTurn = true;
boolean playerTurn2 = false;
public void moveC1Up() {
counterY1 -= 51 * diceRoll();
}
public void moveC2Up() {
counterY2 -= 51 * diceRoll();
}
public void moveC3Up() {
counterY3 -= 51 * diceRoll();
}
public void moveC4Up() {
counterY4 -= 51 * diceRoll();
}
public int diceRoll() {
int randGen = (int) (Math.random() * 1) + 1;
System.out.print(randGen);
return randGen;
}
private JButton moveC1But, moveC2But, rollDiceButton;
private JLabel amountRolledLabel;
public Game() {
JFrame window = new JFrame("Main Game");
final JPanel firstPanel = new JPanel(new GridLayout(3, 1)) {
private static final long serialVersionUID = -1729570833533906839L;
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
super.paintComponent(g2d);
int width = getWidth() / 3;
int height = getHeight() / 11;
for (int i = 0; i < 4; i++) {
g.drawLine(i * width, 0, i * width, getHeight());
}
for (int i = 0; i < 11; i++) {
g.drawLine(0, i * height, getWidth(), i * height);
}
g.setColor(Color.DARK_GRAY);
g.drawOval(220, counterY1, 40, 40);
g.fillOval(220, counterY1, 40, 40);
g.drawOval(300, counterY2, 40, 40);
g.fillOval(300, counterY2, 40, 40);
g.setColor(Color.LIGHT_GRAY);
g.drawOval(410, counterY3, 40, 40);
g.fillOval(410, counterY3, 40, 40);
g.drawOval(490, counterY4, 40, 40);
g.fillOval(490, counterY4, 40, 40);
}
};
JPanel mainPanel = new JPanel(new BorderLayout());
mainPanel.add(firstPanel, BorderLayout.CENTER);
JPanel rightSidePanel = new JPanel(new GridLayout(10, 1));
moveC1But = new JButton("Move Counter 1");
moveC1But.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
diceRoll();
moveC1Up();
firstPanel.repaint();
playerTurn = false;
playerTurn2 = true;
}
});
moveC2But = new JButton("Move Counter 2");
moveC2But.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
diceRoll();
moveC3Up();
firstPanel.repaint();
playerTurn = false;
playerTurn2 = true;
}
});
rollDiceButton = new JButton("Roll Dice");
rightSidePanel.add(moveC1But, BorderLayout.LINE_START);
rightSidePanel.add(moveC2But, BorderLayout.LINE_END);
rightSidePanel.add(rollDiceButton, BorderLayout.SOUTH);
mainPanel.add(rightSidePanel, BorderLayout.EAST);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.getContentPane().add(mainPanel);
window.setSize(700, 600);
window.setLocationRelativeTo(null);
window.setVisible(true);
window.setResizable(false);
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Game();
}
});
}
}
I have searched the internet trying to fix my problem. The whoWon.setText() part is not updating the JLabel.
The part where it should update the JLabel is in the PlayAgain.java file under the comment
//Get Winner
I have tried repaint() and postInvalidate() and still it is not working. There must be something I am missing.
Here is the code:
TicTacToe.java =>
package ticTacToe;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Frame;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TicTacToe extends JFrame implements ActionListener {
private JPanel contentPane;
boolean winner = false;
boolean draw = false;
byte count = 0;
String btnLabel;
PlayAgain playAgain = new PlayAgain();
JButton btn1 = new JButton("");
JButton btn2 = new JButton("");
JButton btn3 = new JButton("");
JButton btn4 = new JButton("");
JButton btn5 = new JButton("");
JButton btn6 = new JButton("");
JButton btn7 = new JButton("");
JButton btn8 = new JButton("");
JButton btn9 = new JButton("");
static TicTacToe frame = new TicTacToe();
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public TicTacToe() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 616, 637);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
btn1.setBounds(0, 0, 200, 200);
btn1.addActionListener(this);
contentPane.add(btn1);
btn2.setBounds(200, 0, 200, 200);
btn2.addActionListener(this);
contentPane.add(btn2);
btn3.setBounds(400, 0, 200, 200);
btn3.addActionListener(this);
contentPane.add(btn3);
btn4.setBounds(0, 200, 200, 200);
btn4.addActionListener(this);
contentPane.add(btn4);
btn5.setBounds(200, 200, 200, 200);
btn5.addActionListener(this);
contentPane.add(btn5);
btn6.setBounds(400, 200, 200, 200);
btn6.addActionListener(this);
contentPane.add(btn6);
btn7.setBounds(0, 400, 200, 200);
btn7.addActionListener(this);
contentPane.add(btn7);
btn8.setBounds(200, 400, 200, 200);
btn8.addActionListener(this);
contentPane.add(btn8);
btn9.setBounds(400, 400, 200, 200);
btn9.addActionListener(this);
contentPane.add(btn9);
}
//Main Code
#Override
public void actionPerformed(ActionEvent e) {
//Play label (Player 1 = X, Player 2 = O)
if(count==0 || count==2 || count==4 || count==6 || count==8){
btnLabel = "X";
}else btnLabel = "O";
count++;
//Clicking buttons
if(e.getSource()==btn1){
btn1.setText(btnLabel);
btn1.setEnabled(false);
btn1.setBackground(Color.BLACK);
}
else if(e.getSource()==btn2){
btn2.setText(btnLabel);
btn2.setEnabled(false);
btn2.setBackground(Color.BLACK);
}
else if(e.getSource()==btn3){
btn3.setText(btnLabel);
btn3.setEnabled(false);
btn3.setBackground(Color.BLACK);
}
else if(e.getSource()==btn4){
btn4.setText(btnLabel);
btn4.setEnabled(false);
btn4.setBackground(Color.BLACK);
}
else if(e.getSource()==btn5){
btn5.setText(btnLabel);
btn5.setEnabled(false);
btn5.setBackground(Color.BLACK);
}
else if(e.getSource()==btn6){
btn6.setText(btnLabel);
btn6.setEnabled(false);
btn6.setBackground(Color.BLACK);
}
else if(e.getSource()==btn7){
btn7.setText(btnLabel);
btn7.setEnabled(false);
btn7.setBackground(Color.BLACK);
}
else if(e.getSource()==btn8){
btn8.setText(btnLabel);
btn8.setEnabled(false);
btn8.setBackground(Color.BLACK);
}
else if(e.getSource()==btn9){
btn9.setText(btnLabel);
btn9.setEnabled(false);
btn9.setBackground(Color.BLACK);
}
//Win Conditions
//Horizontal
if(btn1.getText().equals(btn2.getText())&&btn2.getText().equals(btn3.getText())&!btn1.getText().equals("")){
winner = true;
afterGame(btnLabel);
}
else if(btn4.getText().equals(btn5.getText())&&btn5.getText().equals(btn6.getText())&!btn4.getText().equals("")){
winner = true;
afterGame(btnLabel);
}
else if(btn7.getText().equals(btn8.getText())&&btn8.getText().equals(btn9.getText())&!btn7.getText().equals("")){
winner = true;
afterGame(btnLabel);
}
//Vertical
else if(btn1.getText().equals(btn4.getText())&&btn4.getText().equals(btn7.getText())&!btn1.getText().equals("")){
winner = true;
afterGame(btnLabel);
}
else if(btn2.getText().equals(btn5.getText())&&btn5.getText().equals(btn8.getText())&!btn2.getText().equals("")){
winner = true;
afterGame(btnLabel);
}
else if(btn3.getText().equals(btn6.getText())&&btn6.getText().equals(btn9.getText())&!btn3.getText().equals("")){
winner = true;
afterGame(btnLabel);
}
//Diagonal
else if(btn1.getText().equals(btn5.getText())&&btn5.getText().equals(btn9.getText())&!btn1.getText().equals("")){
winner = true;
afterGame(btnLabel);
}
else if(btn3.getText().equals(btn5.getText())&&btn5.getText().equals(btn7.getText())&!btn3.getText().equals("")) {
winner = true;
afterGame(btnLabel);
}
//Draw
else if(count==9&winner==false)System.out.println("Game is draw");
}
public void afterGame(String btnName){
playAgain.getWinner(btnName);
playAgain = new PlayAgain();
playAgain.setVisible(true);
frame.dispose();
}
}
PlayAgain.java =>
package ticTacToe;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import java.awt.Font;
import javax.swing.JButton;
public class PlayAgain extends JFrame {
private JPanel contentPane;
JLabel whoWon = new JLabel();
static PlayAgain frame = new PlayAgain();
String winner;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public PlayAgain() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 153);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
whoWon.setText(" ");
whoWon.setFont(new Font("Tahoma", Font.BOLD, 18));
whoWon.setBounds(10, 11, 414, 48);
contentPane.add(whoWon);
JButton playAgain = new JButton("Play Again!");
playAgain.setBounds(10, 70, 200, 34);
contentPane.add(playAgain);
JButton exit = new JButton("Quit!");
exit.setBounds(220, 70, 204, 34);
contentPane.add(exit);
}
//Get Winner
public void getWinner(String player){
System.out.println("getWinner()");
System.out.println("btnName: " + player);
if(player.equals("X")){
System.out.println("Player 1 won");
whoWon.setText("Player 1 has won!");
repaint();
}
else {
System.out.println("Player 2 won");
whoWon.setText("Player 2 has won!");
repaint();
}
}
}
EDIT: System.out.println() are there to help me follow the program's steps
I think your problem is in method afterGame . You call getWinner method for one instance and then, in next line, create a new one with empty value , because of that your label doesn't change text . You see a new instance of object.
You mustn't check string equality with ==. Use equals:
if (player.equals("X"))
btn1.getText()==btn2.getText() is bad equality check too...
Do this somewhere before the label is updated ans see if it helps. If the label isnt updating, it might be because it isnt editable/enabled.
whoWon.setEditable(true);