问题
I\'m trying to create a hangman game and so far it\'s coming along GREAT, but the layout design just doesn\'t seem to fall into place! The alphabet is supposed to end up in a FlowLayout
order on top of the Hangman picture with the buttons \"Restart\", \"Help\" \"Add New Word\" and \"Exit\" at the bottom! What am I doing wrong?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
public class Hangman extends JFrame
{
int i = 0;
static JPanel panel;
static JPanel panel2;
static JPanel panel3;
public Hangman()
{
JButton[] buttons = new JButton[26];
panel = new JPanel(new FlowLayout());
panel2 = new JPanel();
panel3 = new JPanel();
JButton btnRestart = new JButton(\"Restart\");
btnRestart.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
}
});
JButton btnNewWord = new JButton(\"Add New Word\");
btnNewWord.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
try
{
FileWriter fw = new FileWriter(\"Words.txt\", true);
PrintWriter pw = new PrintWriter(fw, true);
String word = JOptionPane.showInputDialog(\"Please enter a word: \");
pw.println(word);
pw.close();
}
catch(IOException ie)
{
System.out.println(\"Error Thrown\" + ie.getMessage());
}
}
});
JButton btnHelp = new JButton(\"Help\");
btnHelp.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
String message = \"The word to guess is represented by a row \"
+ \"of dashes, giving the number of letters and category of \"
+ \"the word. \\nIf the guessing player suggests a letter \"
+ \"which occurs in the word, the other player writes it \"
+ \"in all its correct positions. \\nIf the suggested \"
+ \"letter does not occur in the word, the other player \"
+ \"draws one element of the hangman diagram as a tally mark.\"
+ \"\\n\"
+ \"\\nThe game is over when:\"
+ \"\\nThe guessing player completes the word, or guesses \"
+ \"the whole word correctly\"
+ \"\\nThe other player completes the diagram\";
JOptionPane.showMessageDialog(null,message, \"Help\",JOptionPane.INFORMATION_MESSAGE);
}
});
JButton btnExit = new JButton(\"Exit\");
btnExit.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
});
ImageIcon icon = new ImageIcon(\"D:\\\\Varsity College\\\\Prog212Assign1_10-013803\\\\images\\\\Hangman1.jpg\");
JLabel label = new JLabel();
label.setIcon(icon);
String b[]= {\"A\",\"B\",\"C\",\"D\",\"E\",\"F\",\"G\",\"H\",\"I\",\"J\",\"K\",\"L\",\"M\",\"N\",\"O\",\"P\",\"Q\",\"R\",\"S\",\"T\",\"U\",\"V\",\"W\",\"X\",\"Y\",\"Z\"};
for(i = 0; i < buttons.length; i++)
{
buttons[i] = new JButton(b[i]);
panel.add(buttons[i]);
}
panel2.add(label);
panel3.add(btnRestart);
panel3.add(btnNewWord);
panel3.add(btnHelp);
panel3.add(btnExit);
}
public static void main(String[] args)
{
Hangman frame = new Hangman();
frame.add(panel, BorderLayout.NORTH);
frame.add(panel2, BorderLayout.CENTER);
frame.add(panel3, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
}
回答1:
Here are a few suggestions:
Use a
GridLayout
for the top panel; in this case, zero means the number of rows is determined by the specified number of columns and the total number of components in the layout:JPanel north = new JPanel(new GridLayout(0, 9));
Here's an outline of how you can make your center panel have a reasonable initial size; note how you can draw relative to the current size:
JPanel center = new JPanel() { private static final int N = 256; private static final String S = "Todo..."; @Override protected void paintComponent(Graphics g) { super.paintComponent(g); int dx = (getWidth() - g.getFontMetrics().stringWidth(S)) / 2; int dy = getHeight() / 2; g.drawString(S, dx, dy); } @Override public Dimension getPreferredSize() { return new Dimension(N, N); } };
You can construct your button names like this:
for (int i = 0; i < 26; i++) { String letter = String.valueOf((char) (i + 'A')); buttons[i] = new JButton(letter); north.add(buttons[i]); }
Make your panels instance variables and start on the event dispatch thread:
EventQueue.invokeLater(new Runnable() { @Override public void run() { Hangman frame = new Hangman(); frame.setDefaultCloseOperation(EXIT_ON_CLOSE); frame.add(frame.north, BorderLayout.NORTH); frame.add(frame.center, BorderLayout.CENTER); frame.add(frame.south, BorderLayout.SOUTH); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); } });
回答2:
This problem is pretty well documented if you do some research - it seems all the panels (besides the CENTER one) aren't recalculated when resized. See How do I make this FlowLayout wrap within its JSplitPane? and http://www.velocityreviews.com/forums/t608472-wrap-flowlayout.html
But for a really quick fix, try changing your main
method to this... (basically using a BoxLayout as your main container)
public static void main(String[] args)
{
TempProject frame = new TempProject();
Box mainPanel = Box.createVerticalBox();
frame.setContentPane(mainPanel);
mainPanel.add(panel);
mainPanel.add(panel2);
mainPanel.add(panel3);
frame.pack();
frame.setVisible(true);
}
来源:https://stackoverflow.com/questions/12023334/flowlayout-on-top-of-gridlayout-not-working