FlowLayout su GridLayout non funziona

Sto provando a creare un gioco dell’impiccato e finora è arrivato GRANDE, ma il design del layout non sembra proprio andare al suo posto! L’alfabeto dovrebbe finire in un ordine FlowLayout in cima all’immagine Hangman con i pulsanti “Riavvia”, “Aiuto” “Aggiungi nuova parola” e “Esci” in fondo! Che cosa sto facendo di sbagliato?

boia

 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 actionPerformsd(ActionEvent e) { } }); JButton btnNewWord = new JButton("Add New Word"); btnNewWord.addActionListener(new ActionListener(){ public void actionPerformsd(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 actionPerformsd(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 actionPerformsd(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); } } 

Ecco alcuni suggerimenti:

inserisci la descrizione dell'immagine qui

  • Usa un GridLayout per il pannello superiore; in questo caso, zero significa che il numero di righe è determinato dal numero di colonne specificato e dal numero totale di componenti nel layout:

     JPanel north = new JPanel(new GridLayout(0, 9)); 
  • Ecco uno schema di come è ansible rendere il pannello centrale di dimensioni iniziali ragionevoli; nota come puoi disegnare rispetto alla dimensione attuale:

     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); } }; 
  • Puoi build i nomi dei pulsanti in questo modo:

     for (int i = 0; i < 26; i++) { String letter = String.valueOf((char) (i + 'A')); buttons[i] = new JButton(letter); north.add(buttons[i]); } 
  • Crea le variabili di istanza dei pannelli e avvia il thread di invio degli eventi :

     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); } }); 

Questo problema è ben documentato se fai qualche ricerca: sembra che tutti i pannelli (oltre a quello di CENTER) non vengano ricalcolati quando ridimensionati. Vedi Come faccio a rendere questo avvolgimento FlowLayout all’interno del suo JSplitPane? e http://www.velocityreviews.com/forums/t608472-wrap-flowlayout.html

Ma per una soluzione davvero rapida, prova a cambiare il metodo main con questo … (fondamentalmente usando un BoxLayout come contenitore principale)

 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); }