Results 1 to 6 of 6
- 10-19-2011, 07:50 PM #1
Member
- Join Date
- Oct 2011
- Posts
- 41
- Rep Power
- 0
frame not displaying correct contents
I am working on a program that allows two people to play chess. I created a frame that allows a user to select a piece to promote a pawn to when the reach the 8th rank. The problem is, when I create this frame from my main method, it displays fine, but when I create it from my mouse listener, which is where its supposed to be created, it shows a 2x4 checkered pattern, and im not sure why. To be more clear, it actually displays whatever is behind it when its created, because I experimented with displaying it in different locations. if you need any more source, let me know, otherwise here is the relevant source code:
[\code]Java Code:import java.awt.*; import javax.swing.*; import javax.swing.border.*; import java.awt.event.*; public class PromotionFrame extends JFrame implements MouseListener { private JFrame master; private String piece; public PromotionFrame(JFrame master, int color) { super(); this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); Container con = this.getContentPane(); setSize(400,200); this.master = master; setLocation(master.getX()+master.getWidth()/2-200,master.getY()+master.getHeight()/2-100); con.setLayout(new GridLayout(1,4)); ImageIcon imgicon1; Image img1; Image newimg; ImageIcon img; ImageLabel label; piece = null; if(color == Colors.WHITE) imgicon1 = new ImageIcon("wq.png"); else imgicon1 = new ImageIcon("bq.png"); img1 = imgicon1.getImage(); newimg = img1.getScaledInstance(100, 100, java.awt.Image.SCALE_SMOOTH); img = new ImageIcon(newimg); label = new ImageLabel(img, "queen"); label.addMouseListener(this); con.add(label); if(color == Colors.WHITE) imgicon1 = new ImageIcon("wr.png"); else imgicon1 = new ImageIcon("br.png"); img1 = imgicon1.getImage(); newimg = img1.getScaledInstance(100, 100, java.awt.Image.SCALE_SMOOTH); img = new ImageIcon(newimg); label = new ImageLabel(img, "rook"); label.addMouseListener(this); con.add(label); if(color == Colors.WHITE) imgicon1 = new ImageIcon("wb.png"); else imgicon1 = new ImageIcon("bb.png"); img1 = imgicon1.getImage(); newimg = img1.getScaledInstance(100, 100, java.awt.Image.SCALE_SMOOTH); img = new ImageIcon(newimg); label = new ImageLabel(img, "bishop"); label.addMouseListener(this); con.add(label); if(color == Colors.WHITE) imgicon1 = new ImageIcon("wn.png"); else imgicon1 = new ImageIcon("bn.png"); img1 = imgicon1.getImage(); newimg = img1.getScaledInstance(100, 100, java.awt.Image.SCALE_SMOOTH); img = new ImageIcon(newimg); label = new ImageLabel(img, "knight"); label.addMouseListener(this); con.add(label); this.show(); } public String getPiece() { return piece; } /* Empty method definition. */ public void mousePressed(MouseEvent e) { ImageLabel label = (ImageLabel)e.getSource(); piece = label.getPiece(); } /* Empty method definition. */ public void mouseReleased(MouseEvent e) { } /* Empty method definition. */ public void mouseEntered(MouseEvent e) { } /* Empty method definition. */ public void mouseExited(MouseEvent e) { } public void mouseClicked(MouseEvent e) { } private class ImageLabel extends JLabel { private String piece; ImageLabel(ImageIcon img, String piece) { super(img); this.piece = piece; } public String getPiece() { return piece; } } } import java.awt.*; import javax.swing.*; import java.awt.event.*; public class GameFrame extends JFrame { private SquarePanel[][] squares; public GameFrame(Game game) { this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container con = this.getContentPane(); setSize(800,800); setLocation(0,0); con.setLayout(new GridLayout(8,8)); SquarePanel pane = null; SquarePanel lastpanel = null; squares = new SquarePanel[8][8]; int color = Colors.WHITE; for(int i = 7; i >= 0; --i) { if(color == Colors.WHITE) color = Colors.BLACK; else color = Colors.WHITE; for(int j = 0; j <= 7; ++j) { if(color == Colors.WHITE) color = Colors.BLACK; else color = Colors.WHITE; lastpanel = new SquarePanel(color,j,i); pane = lastpanel; con.add(pane); squares[j][i] = pane; } } Board board = game.getBoard(); for(int i = 0; i < 8; ++i) { for(int j = 0; j < 8; ++j) { squares[j][i].setResident(board.getSquare(j,i).getResident()); //System.out.println(squares[j][i].getResident()); //squares[j][i].repaint(); } } MouseListener listener = new MoveListener(game, this, squares); for(int i = 0; i < 8; ++i) for(int j = 0; j < 8; ++j) squares[i][j].addMouseListener(listener); setVisible(true); } public static void main(String[] args) { GameFrame g = new GameFrame(new Game()); PromotionFrame pframe = new PromotionFrame(g, 1); String piece; Piece p2; do { piece = pframe.getPiece(); } while(piece == null); pframe.dispose(); } } import java.awt.*; import java.awt.event.*; import javax.swing.*; public class MoveListener implements MouseListener { private int first_click; private SquarePanel first_source; private Game game; private JFrame frame; private int turn; private SquarePanel[][] squares; public MoveListener(Game game, JFrame f, SquarePanel[][] s) { first_click = 0; this.game = game; this.frame = f; turn = Colors.WHITE; squares = s; } /* Empty method definition. */ public void mousePressed(MouseEvent e) { SquarePanel p = (SquarePanel)e.getSource(); ImageIcon content = null; if(first_click == 0) { first_source = p; ++first_click; p.setBorder(BorderFactory.createLineBorder(Color.cyan,4)); } else { first_click = 0; first_source.setBorder(BorderFactory.createLineBorder(Color.black)); //System.out.println(turn == Colors.WHITE ? "White" : "Black"); if(first_source.getResident() == null) { new ErrorDialog(frame,"Not a Move"); } else if(first_source.getResident().getColor() != turn) { new ErrorDialog(frame,"Not your turn"); } else if(game.move(first_source.getXCoordinate(), first_source.getYCoordinate(),p.getXCoordinate(), p.getYCoordinate())) { p.setResident(null); p.setResident(first_source.getResident()); first_source.setResident(null); //System.out.println(p.getXCoordinate()+" "+p.getY()); //check to see if this was a promotion if(p.getResident() instanceof Pawn && p.getYCoordinate() == 7) { PromotionFrame pframe = new PromotionFrame(frame, p.getResident().getColor()); String piece; Piece p2; do { piece = pframe.getPiece(); } while(piece == null); pframe.dispose(); p2 = game.promote((Pawn)p.getResident(),piece); p.setResident(p2); } if(game.checkMate(turn)) { if(turn == Colors.WHITE) new ErrorDialog(frame, "Game over: Black wins"); else new ErrorDialog(frame, "Game over: White wins"); } game.dump(); } else { new ErrorDialog(frame,"Illegal Move"); } //game.displayAttacks(); } } /* Empty method definition. */ public void mouseReleased(MouseEvent e) { } /* Empty method definition. */ public void mouseEntered(MouseEvent e) { } /* Empty method definition. */ public void mouseExited(MouseEvent e) { } public void mouseClicked(MouseEvent e) { } }Last edited by yemista; 10-19-2011 at 07:57 PM.
- 10-20-2011, 01:22 AM #2
Member
- Join Date
- Oct 2011
- Posts
- 41
- Rep Power
- 0
Re: frame not displaying correct contents
if youd like, i also have trimmed the code down a bit to a compilable example. just copy and paste the following into Example.java, compile and run. When you run it, the promotion frame should come up correctly the first time. click on a string within it to make it go away. after that, click any square, then click on a square in the top row and it will come up incorrectly and you will see the bug
Java Code:import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*; public class Example extends JFrame { private SquarePanel[][] squares; private Colors colors; public Example () { super(); colors = new Colors(); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container con = this.getContentPane(); setSize(800,800); setLocation(0,0); con.setLayout(new GridLayout(8,8)); SquarePanel pane = null; SquarePanel lastpanel = null; squares = new SquarePanel[8][8]; int color = colors.WHITE; for(int i = 7; i >= 0; --i) { if(color == colors.WHITE) color = colors.BLACK; else color = colors.WHITE; for(int j = 0; j <= 7; ++j) { if(color == colors.WHITE) color = colors.BLACK; else color = colors.WHITE; lastpanel = new SquarePanel(color,j,i); pane = lastpanel; con.add(pane); squares[j][i] = pane; } } for(int i = 0; i < 8; ++i) { for(int j = 0; j < 8; ++j) { squares[j][i].setResident("pawn"); //System.out.println(squares[j][i].getResident()); //squares[j][i].repaint(); } } MouseListener listener = new MoveListener(this, squares); for(int i = 0; i < 8; ++i) for(int j = 0; j < 8; ++j) squares[i][j].addMouseListener(listener); setVisible(true); PromotionFrame pf = new PromotionFrame(this, 1); String p = null; while(p == null) { p = pf.getPiece(); } pf.dispose(); } public class SquarePanel extends JPanel { private ImageIcon content; private int x; private int y; private int color; private String resident; private Colors colors; public SquarePanel(int color, int x, int y) { content = null; resident = null; colors = new Colors(); this.color = color; this.x = x; this.y = y; Border blackline = BorderFactory.createLineBorder(Color.black); setBorder(blackline); this.setLayout(new GridBagLayout()); } public void paintComponent(Graphics g) { super.paintComponent(g); int width = getWidth(); int height = getHeight(); if(color == colors.WHITE) g.setColor(Color.white); else g.setColor(Color.green); g.fillRect(0, 0, width, height); g.setColor(Color.black); //System.out.println("here"); } public String getResident() { return resident; } public void setResident(String p) { resident = p; if(p == null) removeAll(); else add(new JLabel(p)); } public int getXCoordinate() { return x; } public int getYCoordinate() { return y; } } private class Colors { public int BLACK = 0; public int WHITE = 1; } public class MoveListener implements MouseListener { private int first_click; private SquarePanel first_source; private JFrame frame; private int turn; private SquarePanel[][] squares; public MoveListener(JFrame f, SquarePanel[][] s) { first_click = 0; this.frame = f; turn = colors.WHITE; squares = s; } /* Empty method definition. */ public void mousePressed(MouseEvent e) { SquarePanel p = (SquarePanel)e.getSource(); ImageIcon content = null; if(first_click == 0) { first_source = p; ++first_click; p.setBorder(BorderFactory.createLineBorder(Color.cyan,4)); } else { first_click = 0; first_source.setBorder(BorderFactory.createLineBorder(Color.black)); //System.out.println(turn == colors.WHITE ? "White" : "Black"); if(p.getResident().equals("pawn") && (p.getYCoordinate() == 7 || p.getYCoordinate() == 0)) { PromotionFrame pframe = new PromotionFrame(frame, colors.WHITE); String piece; do { piece = pframe.getPiece(); } while(piece == null); System.out.println(piece); pframe.dispose(); p.setResident(piece); } } } /* Empty method definition. */ public void mouseReleased(MouseEvent e) { } /* Empty method definition. */ public void mouseEntered(MouseEvent e) { } /* Empty method definition. */ public void mouseExited(MouseEvent e) { } public void mouseClicked(MouseEvent e) { } } public class PromotionFrame extends JFrame implements MouseListener { private JFrame master; private String piece; public PromotionFrame(JFrame master, int color) { super(); this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); Container con = this.getContentPane(); setSize(400,200); this.master = master; setLocation(master.getX()+master.getWidth()/2-200,master.getY()+master.getHeight()/2-100); setLocation(0,0); con.setLayout(new GridLayout(1,4)); ImageIcon imgicon1; Image img1; Image newimg; ImageIcon img; ImageLabel label; piece = null; label = new ImageLabel("queen"); label.addMouseListener(this); con.add(label); label = new ImageLabel("rook"); label.addMouseListener(this); con.add(label); label = new ImageLabel("bishop"); label.addMouseListener(this); con.add(label); label = new ImageLabel("knight"); label.addMouseListener(this); con.add(label); this.show(); } public String getPiece() { return piece; } /* Empty method definition. */ public void mousePressed(MouseEvent e) { ImageLabel label = (ImageLabel)e.getSource(); piece = label.getPiece(); } /* Empty method definition. */ public void mouseReleased(MouseEvent e) { } /* Empty method definition. */ public void mouseEntered(MouseEvent e) { } /* Empty method definition. */ public void mouseExited(MouseEvent e) { } public void mouseClicked(MouseEvent e) { } private class ImageLabel extends JLabel { private String piece; ImageLabel(String piece) { super(piece); this.piece = piece; } public String getPiece() { return piece; } } } public static void main(String[] args) { new Example(); } }
-
Re: frame not displaying correct contents
Your do/while loops are killing you by freezing up the event thread. You should use a listener for this instead, not a futile loop. And don't use another JFrame but rather a modal JDialog.
-
Re: frame not displaying correct contents
Also 90% of the code in your "small" example is completely unrelated to your problem, and I ask that next time you post a similar question, you don't force us to slog through this unrelated and confusing code.
-
Re: frame not displaying correct contents
For example, this code mimics your code by launching a JFrame, and looping in a while loop awaiting the change of a variable from null to a non-null variable. Again, it's the loop that totally locks the thread that calls it, and that thread is the Swing event thread. So the loop makes Swing completely unresponsive and the smaller pop-up JFrame never has its labels painted, and both JFrames become unresponsive and can't be exited:
Java Code:import java.awt.*; import java.awt.event.*; import javax.swing.*; @SuppressWarnings("serial") public class ExampleBad extends JPanel { private static final int PREF_WIDTH = 400; private static final int PREF_HEIGHT = PREF_WIDTH; private JLabel label = new JLabel("Empty", SwingConstants.CENTER); public ExampleBad() { setLayout(new BorderLayout()); add(label); addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { JFrame frame = (JFrame)SwingUtilities.getWindowAncestor(ExampleBad.this); PromoBad promo = new PromoBad(frame); promo.setVisible(true); String piece = null; // this code below locks the event thread // making the dialog GUI not paint itself // and makes both GUIs unresponsive while (piece == null) { piece = promo.getPiece(); } promo.dispose(); label.setText(piece); } }); } @Override public Dimension getPreferredSize() { return new Dimension(PREF_WIDTH, PREF_HEIGHT); } private static void createAndShowGui() { ExampleBad mainPanel = new ExampleBad(); JFrame frame = new JFrame("ExampleBad"); frame.setDefaultCloseOperation(JFrame.EXIT_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(); } }); } } class PromoBad extends JFrame { private String piece = null; public PromoBad(JFrame frame) { super("Promo"); setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); JPanel panel = new JPanel(new GridLayout(1, 0)); MouseListener ml = new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { JLabel label = (JLabel)e.getSource(); piece = label.getText(); } }; JLabel[] labels = {new JLabel("Foo"), new JLabel("bar"), new JLabel("baz")}; for (JLabel label : labels) { label.addMouseListener(ml); panel.add(label); } add(panel); pack(); setLocationRelativeTo(frame); } public String getPiece() { return piece; } }
On the other hand, here's an example that uses a modal JDialog instead of a second JFrame. The advantage is that the JFrame code stops right where the dialog has been set visible, and the JFrame doesn't resume until the dialog has been disposed or made invisible. So you can collect the String from the dialog on the next line after you set it visible true. There's no non-stopping while loop so Swing stays responsive and the dialog labels, foo, bar, baz, get painted:
Java Code:import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ExampleGood extends JPanel { private static final int PREF_WIDTH = 400; private static final int PREF_HEIGHT = PREF_WIDTH; private JLabel label = new JLabel("Empty", SwingConstants.CENTER); public ExampleGood() { setLayout(new BorderLayout()); add(label); addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { JFrame frame = (JFrame)SwingUtilities.getWindowAncestor(ExampleGood.this); PromoGood promo = new PromoGood(frame); promo.setVisible(true); // this code is called only after the dialog has been disposed String piece = promo.getPiece(); label.setText(piece); } }); } @Override public Dimension getPreferredSize() { return new Dimension(PREF_WIDTH, PREF_HEIGHT); } private static void createAndShowGui() { ExampleGood mainPanel = new ExampleGood(); JFrame frame = new JFrame("ExampleGood"); frame.setDefaultCloseOperation(JFrame.EXIT_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(); } }); } } // make this a JDialog class PromoGood extends JDialog { private String piece = null; public PromoGood(JFrame frame) { super(frame, "Promo", true); // make it a modal dialog MouseListener ml = new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { JLabel label = (JLabel)e.getSource(); piece = label.getText(); PromoGood.this.dispose(); // dispose of the dialog } }; JPanel panel = new JPanel(new GridLayout(1, 0)); JLabel[] labels = {new JLabel("Foo"), new JLabel("bar"), new JLabel("baz")}; for (JLabel label : labels) { label.addMouseListener(ml); panel.add(label); } add(panel); pack(); setLocationRelativeTo(frame); } public String getPiece() { return piece; } }
- 10-20-2011, 05:30 PM #6
Member
- Join Date
- Oct 2011
- Posts
- 41
- Rep Power
- 0
Re: frame not displaying correct contents
ok, got it working. i understand now that I should never use a while loop to poll within an event handler. There is still one minor bug, its not a big deal and I can live with it, but the problem is, when you promote a piece, the image stays as a pawn until the next mouse event. here is the relevant code(real short this time!)
The first part is what handles switching around pieces in case of a normal move. the conditional takes care of the instance when its a promotion. as you can see, the three lines that change the image (setResident()) are identical, however, in the conditional it only does it after the next mouse event. I addedJava Code:p.setResident(null); p.setResident(first_source.getResident()); first_source.setResident(null); //System.out.println(p.getXCoordinate()+" "+p.getY()); //check to see if this was a promotion if(p.getResident() instanceof Pawn && (p.getYCoordinate() == 7 || p.getYCoordinate() == 0)) { PromotionFrame pframe = new PromotionFrame(frame, p.getResident().getColor()); String piece; Piece p2; //System.out.println("here6"); piece = pframe.getPiece(); p2 = game.promote((Pawn)p.getResident(),piece); p.setResident(null); p.setResident(p2); }
to my code to see if this fixed it, and it didnt, and i also trued throwing in a repaint() statement . once again, this isnt a huge deal to me, its more of a pet peeve, and i wanna thank you again for your help. swing code has lots of gotchas to it that i never knew existedJava Code:SwingUtilities.invokeLater(new Runnable() { public void run() { GameFrame g = new GameFrame(new Game()); } });
Similar Threads
-
How to set Jpanel in the center of frame when Increase the size of frame
By justbeller in forum AWT / SwingReplies: 4Last Post: 01-18-2011, 08:22 AM -
Java slave Frame access to its owner main frame problem
By cagdaseckin in forum New To JavaReplies: 0Last Post: 12-10-2010, 10:40 AM -
How to get(copy) the contents i.e the contents in the cells of an excel sheet
By johnvarg in forum AWT / SwingReplies: 1Last Post: 02-23-2010, 09:48 AM -
Frame contents not displaying when called from elsewhere
By LoupGarou in forum AWT / SwingReplies: 4Last Post: 10-30-2009, 10:38 PM -
Help frame is not displaying.
By gammaman in forum New To JavaReplies: 24Last Post: 07-22-2009, 01:00 PM


LinkBack URL
About LinkBacks
Reply With Quote
Bookmarks