2014-06-18 21 views
5

Sto cercando di creare la seguente GUI:GridBagLayout gridding non funziona

enter image description here

ma l'interfaccia grafica che mi faccio è:

enter image description here

Ciò che appare la mia griglia come:

immagine: THE GRIDLAYOUT FOR THIS

Non capisco perché sto ottenendo questo risultato poiché ho disegnato un diagramma per aiutare il codice e sembra funzionare.

Il metodo addComp aggiunge aggiunge il componente di input al pannello di input in una data posizione (x, y) e ad una larghezza e altezza di un determinato componente.

Codice:

import javax.swing.*; 
import java.awt.*; 

public class GUIError extends JFrame { 

    //initialise all the components 
    JPanel mainPanel = new JPanel(); 
    JTextField txtDisplay = new JTextField(); 
    JButton btnA = new JButton("A"); 
    JButton btnB = new JButton("B"); 
    JButton btnC = new JButton("C"); 
    JButton btnD = new JButton("D"); 
    JButton btnE = new JButton("E"); 
    JButton btnF = new JButton("F"); 
    JButton btnWA = new JButton("WA"); 
    JButton btnWB = new JButton("WB"); 
    JButton btnWC = new JButton("WC"); 
    JButton btnWD = new JButton("WD"); 

    private void addComp(JPanel panel, JComponent comp, int xPos, int yPos, int compWidth, int compHeight) { 

     GridBagConstraints gridConstraints = new GridBagConstraints(); 

     gridConstraints.gridx = xPos; 
     gridConstraints.gridy = yPos; 
     gridConstraints.gridwidth = compWidth; 
     gridConstraints.gridheight = compHeight; 
     gridConstraints.weightx = 0.5; 
     gridConstraints.weighty = 0.5; 
     gridConstraints.insets = new Insets(5, 5, 5, 5); 
     gridConstraints.anchor = GridBagConstraints.CENTER; 
     gridConstraints.fill = GridBagConstraints.BOTH; 

     panel.add(comp, gridConstraints); 

    } 


    public static void main(String[] args) { 
     try { 
      for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { 
       if ("Nimbus".equals(info.getName())) { 
        UIManager.setLookAndFeel(info.getClassName()); 
        break; 
       } 
      } 
     } 
     catch (Exception e) { } 

     SwingUtilities.invokeLater(new Runnable() { 

      public void run() { 

       // create frame 
       JFrame frame = new JFrame("Calculator"); 
       frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
       frame.setLocationRelativeTo(null); 
       Container c = frame.getContentPane(); 

       // create GUI within frame    
       new GUIError(c); 

       // finish frame definition 
       frame.pack(); 
       frame.setResizable(false); 
       frame.setVisible(true); 

      } 

     }); 
    } 

    public GUIError(Container cont) { 

     cont.setPreferredSize(new Dimension(610, 250)); 

     // parent panel containes every other panel 
     mainPanel.setLayout(new GridBagLayout()); 

     // text display 
     txtDisplay.setEditable(false); 
     addComp(mainPanel, txtDisplay, 0, 0, 12, 2); // width 16, height 2 


     addComp(mainPanel, btnA, 0, 2, 2, 1); 
     addComp(mainPanel, btnB, 2, 2, 2, 1); 
     addComp(mainPanel, btnC, 4, 2, 2, 1); 
     addComp(mainPanel, btnD, 6, 2, 2, 1); 
     addComp(mainPanel, btnE, 8, 2, 2, 1); 
     addComp(mainPanel, btnF, 10, 2, 2, 1); 
     addComp(mainPanel, btnWA, 0, 3, 3, 1); 
     addComp(mainPanel, btnWB, 3, 3, 3, 1); 
     addComp(mainPanel, btnWC, 6, 3, 3, 1); 
     addComp(mainPanel, btnWD, 9, 3, 3, 1); 

     cont.add(mainPanel); 
    } 
} 
+1

GBC sono basati su colonna, +1 per domanda e SSCCE/MCVE, motivo per cui MigLayout (e.i.) sono sviluppati – mKorbel

+0

Non pensare di poterlo fare con solo 1 pannello. 'gridwidth' non può specificare" mezza griglia "per quanto ne so. Penso che la scelta migliore sia quella di utilizzare un layout diverso o di separare i componenti in pannelli diversi (il pannello principale contiene un campo in alto e due pannelli in basso (affiancati): ciascun pannello secondario ha 2 pannelli: uno per i 3 pulsanti più piccoli, uno con i 2 pulsanti più grandi sotto di esso) –

+0

Non ho specificato la metà di una griglia utilizzando la larghezza di griglia. La prima riga di pulsanti è gridwidth = 2 e la terza riga di pulsanti è gridwidth = 3. Non capisco cosa intendi per 3 pulsanti più piccoli e 2 più grandi in basso? La griglia che ho anche collegato mostra la griglia che ho usato in questa situazione. La seconda fila di pulsanti ha le stesse dimensioni, la terza fila di pulsanti ha le stesse dimensioni. Non capisco perché questo non funzionerebbe con GridBagLayout. – user3749872

risposta

5

Si può facilmente essere ottenuto utilizzando GridBagLayout come si vede in questo esempio presentato di seguito. È sufficiente prendere dueuno per ogni ROW. Sia con GridBagLayout, e aggiungere componenti alla prima fila, con weightx = 0.16 poiché ogni JButton è supponiamo di prendere questo molto zona, e per la seconda fila weightx = 0.25 poiché, questa è l'area occupata da ciascun JButton lungo direzione X

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class GridBagExample { 
    private static final int SIZE = 10; 
    private JButton[] buttons; 
    private GridBagConstraints gbc; 

    public GridBagExample() { 
     buttons = new JButton[SIZE]; 
     gbc = new GridBagConstraints(); 
     gbc.insets = new Insets(5, 5, 5, 5); 
    } 

    private void createAndDisplayGUI() { 
     JFrame frame = new JFrame("Grid Game"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 

     JPanel contentPane = new JPanel(); 
     contentPane.setLayout(new GridLayout(2, 1, 5, 5)); 
     contentPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); 

     JPanel topPanel = new JPanel(); 
     JTextField textField = new JTextField(10); 
     //topPanel.add(textField); 

     JPanel buttonPanel = new JPanel(new GridLayout(2, 1, 5, 5)); 
     JPanel headerPanel = new JPanel(new GridBagLayout()); 
     buttons[0] = new JButton("A"); 
     addComp(headerPanel, buttons[0], 0, 0, 0.16, 1.0, 1, 1, GridBagConstraints.BOTH);   
     buttons[1] = new JButton("B"); 
     addComp(headerPanel, buttons[1], 1, 0, 0.16, 1.0, 1, 1, GridBagConstraints.BOTH); 
     buttons[2] = new JButton("C"); 
     addComp(headerPanel, buttons[2], 2, 0, 0.16, 1.0, 1, 1, GridBagConstraints.BOTH); 
     buttons[3] = new JButton("D"); 
     addComp(headerPanel, buttons[3], 3, 0, 0.16, 1.0, 1, 1, GridBagConstraints.BOTH); 
     buttons[4] = new JButton("E"); 
     addComp(headerPanel, buttons[4], 4, 0, 0.16, 1.0, 1, 1, GridBagConstraints.BOTH); 
     buttons[5] = new JButton("F"); 
     addComp(headerPanel, buttons[5], 5, 0, 0.16, 1.0, 1, 1, GridBagConstraints.BOTH); 

     JPanel footerPanel = new JPanel(new GridBagLayout()); 
     buttons[6] = new JButton("WA"); 
     addComp(footerPanel, buttons[6], 0, 0, 0.25, 1.0, 1, 1, GridBagConstraints.BOTH); 
     buttons[7] = new JButton("WB"); 
     addComp(footerPanel, buttons[7], 1, 0, 0.25, 1.0, 1, 1, GridBagConstraints.BOTH); 
     buttons[8] = new JButton("WC"); 
     addComp(footerPanel, buttons[8], 2, 0, 0.25, 1.0, 1, 1, GridBagConstraints.BOTH); 
     buttons[9] = new JButton("WD"); 
     addComp(footerPanel, buttons[9], 3, 0, 0.25, 1.0, 1, 1, GridBagConstraints.BOTH); 
     buttonPanel.add(headerPanel); 
     buttonPanel.add(footerPanel); 

     contentPane.add(textField); 
     contentPane.add(buttonPanel); 

     frame.setContentPane(contentPane); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    private void addComp(JPanel panel, JComponent comp, int x, int y, 
            double wx, double wy, int gw, int gh, int fill) { 
     gbc.gridx = x; 
     gbc.gridy = y; 
     gbc.weightx = wx; 
     gbc.weighty = wy; 
     gbc.gridwidth = gw; 
     gbc.gridheight = gh; 
     gbc.fill = fill; 

     panel.add(comp, gbc); 
    } 

    public static void main(String... args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       new GridBagExample().createAndDisplayGUI(); 
      } 
     }); 
    } 
} 

OUTPUT: GridBagLayout:

gridbagexample

La stessa uscita può essere ottenuto GridLayout, se GridBagLayout non è una necessità in questo caso, come citato nell'esempio seguente:

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class GridBagExample { 
    private static final int SIZE = 10; 
    private JButton[] buttons; 

    public GridBagExample() { 
     buttons = new JButton[SIZE]; 
    } 

    private void createAndDisplayGUI() { 
     JFrame frame = new JFrame("Grid Game"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 

     JPanel contentPane = new JPanel(); 
     contentPane.setLayout(new GridLayout(2, 1, 5, 5)); 
     contentPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); 

     JPanel topPanel = new JPanel(); 
     JTextArea tArea = new JTextArea(5, 30); 
     JScrollPane scroller = new JScrollPane(); 
     scroller.setViewportView(tArea); 
     topPanel.add(scroller); 

     JPanel buttonPanel = new JPanel(new GridLayout(2, 1, 5, 5)); 
     JPanel headerPanel = new JPanel(new GridLayout(1, 0, 5, 5)); 
     buttons[0] = new JButton("A"); 
     headerPanel.add(buttons[0]); 
     buttons[1] = new JButton("B"); 
     headerPanel.add(buttons[1]); 
     buttons[2] = new JButton("C"); 
     headerPanel.add(buttons[2]); 
     buttons[3] = new JButton("D"); 
     headerPanel.add(buttons[3]); 
     buttons[4] = new JButton("E"); 
     headerPanel.add(buttons[4]); 
     buttons[5] = new JButton("F"); 
     headerPanel.add(buttons[5]); 
     JPanel footerPanel = new JPanel(new GridLayout(1, 0, 5, 5)); 
     buttons[6] = new JButton("WA"); 
     footerPanel.add(buttons[6]); 
     buttons[7] = new JButton("WB"); 
     footerPanel.add(buttons[7]); 
     buttons[8] = new JButton("WC"); 
     footerPanel.add(buttons[8]); 
     buttons[9] = new JButton("WD"); 
     footerPanel.add(buttons[9]); 
     buttonPanel.add(headerPanel); 
     buttonPanel.add(footerPanel); 

     contentPane.add(topPanel); 
     contentPane.add(buttonPanel); 

     frame.setContentPane(contentPane); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String... args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       new GridBagExample().createAndDisplayGUI(); 
      } 
     }); 
    } 
} 

OUTPUT: GridLayout: GridBagExample

5

Normalmente Farei pannelli separati, ma hey, a chi non piace una sfida?

Il problema è che alcune colonne non sono ben definite per GBL (non esiste un singolo componente che ne definisca la larghezza), quindi il pulsante WA non sa fino a che punto andare per coprire metà del pulsante B, ecc.

Quindi, ho aggiunto alcuni distanziali a larghezza zero nelle colonne che costituiscono le sezioni necessarie.

Tutto in un pannello:

enter image description here

import java.awt.*; 
import javax.swing.*; 

public class GridBagDemo3 implements Runnable 
{ 
    private JPanel panel; 

    public static void main(String[] args) 
    { 
    SwingUtilities.invokeLater(new GridBagDemo3()); 
    } 

    public void run() 
    { 
    JTextArea text = new JTextArea(10,10); 
    JButton btnA = new JButton("A"); 
    JButton btnB = new JButton("B"); 
    JButton btnC = new JButton("C"); 
    JButton btnD = new JButton("D"); 
    JButton btnE = new JButton("E"); 
    JButton btnF = new JButton("F"); 
    JButton btnWA = new JButton("WA"); 
    JButton btnWB = new JButton("WB"); 
    JButton btnWC = new JButton("WC"); 
    JButton btnWD = new JButton("WD"); 

    panel = new JPanel(new GridBagLayout()); 

    add(text, 0,0, 12,1); 
    add(btnA, 0,1, 2,1); 
    add(btnB, 2,1, 2,1); 
    add(btnC, 4,1, 2,1); 
    add(btnD, 6,1, 2,1); 
    add(btnE, 8,1, 2,1); 
    add(btnF, 10,1, 2,1); 
    add(btnWA, 0,2, 3,1); 
    add(btnWB, 3,2, 3,1); 
    add(btnWC, 6,2, 3,1); 
    add(btnWD, 9,2, 3,1); 

    // SPACERS: define the 2 columns that button B spans 
    //   so that WA and WB can split B, and same for button E 
    add(null, 2,2, 1,1); 
    add(null, 3,2, 1,1); 
    add(null, 8,2, 1,1); 
    add(null, 9,2, 1,1); 

    JFrame frame = new JFrame("Grig Bag"); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.getContentPane().add(panel); 
    frame.pack(); 
    frame.setVisible(true); 
    } 

    private void add(Component comp, int x, int y, int colspan, int rowspan) 
    { 
    GridBagConstraints gbc = new GridBagConstraints(); 
    gbc.gridx = x; 
    gbc.gridy = y; 
    gbc.gridwidth = colspan; 
    gbc.gridheight = rowspan; 
    gbc.weighty = .1; 
    gbc.anchor = GridBagConstraints.CENTER; 
    gbc.fill = GridBagConstraints.BOTH; 
    gbc.insets = new Insets(5,5,5,5); 

    if (comp != null) 
    { 
     gbc.weightx = 1; 
    } 
    else 
    { 
     comp = Box.createHorizontalGlue(); 
     gbc.fill = GridBagConstraints.NONE; 
     gbc.weightx = 0.1; 
     gbc.weighty = 0; 
    } 

    panel.add(comp, gbc); 
    } 
} 
3

se siete ancora interessati a capire il vostro errore: griglia di layout' non è FlowLayout, non si può semplicemente aggiungere componenti ed andando disegnare oggetti nello stesso momento in cui lo legge. In caso di griglia, la macchina virtuale prima legge tutti gli oggetti e poi crea una griglia, la quantità di colonne viene determinata in base a quelle righe che hanno il maggior numero di colonne. Quindi, hai avuto la buona idea di preferire 12 colonne (in questo modo eviti la creazione di un nuovo "Pannello" e risorse di sistema libere), ma per farlo bene devi semplicemente aggiungere 12 spazi vuoti (non solo vuoti ma anche con dimensioni zero) in una delle righe

// text display 
    txtDisplay.setEditable(false); 
    addComp(mainPanel, txtDisplay, 0, 0, 12, 2); // width 16, height 2 



    //now go with empty spaces 
    for(int i=0;i<12;i++){ 
     GridBagConstraints gridConstraints = new GridBagConstraints(); 
     gridConstraints.gridx = i; //12 times "i" 
     gridConstraints.gridy = 1; //you left y=1 empty, so why don't use it 
     gridConstraints.gridwidth = 1; //one column = one space in grid 
     gridConstraints.gridheight = 0; //we don't want it to occupied any space 
     gridConstraints.weightx = 0.5; 
     gridConstraints.weighty = 0.5; 
     gridConstraints.insets = new Insets(0, 0, 0, 0); //same reason, we don't want it to occupied any space 
     gridConstraints.anchor = GridBagConstraints.CENTER; 
     gridConstraints.fill = GridBagConstraints.BOTH ; 

     mainPanel.add(Box.createHorizontalGlue(), gridConstraints); 
    } 


    addComp(mainPanel, btnA, 0, 2, 2, 1); 
    addComp(mainPanel, btnB, 2, 2, 2, 1); 
    addComp(mainPanel, btnC, 4, 2, 2, 1); 
    addComp(mainPanel, btnD, 6, 2, 2, 1); 
    addComp(mainPanel, btnE, 8, 2, 2, 1); 
    addComp(mainPanel, btnF, 10, 2, 2, 1); 
    addComp(mainPanel, btnWA, 0, 3, 3, 1); 
    addComp(mainPanel, btnWB, 3, 3, 3, 1); 
    addComp(mainPanel, btnWC, 6, 3, 3, 1); 
    addComp(mainPanel, btnWD, 9, 3, 3, 1); 
4

@Matthieu scritto -

could you elaborate on GBC are column based? It sounds like an explanation of a problem I noticed...

Penso che in questo modo è stato progettato GridBagLayout, sto sempre con i JLabels (senza frontiere :-) come matrice ..

enter image description here

import java.awt.*; 
import javax.swing.*; 

public class CopyTextNorthPanel extends JPanel { 

    private static final long serialVersionUID = 1L; 
    private JLabel hidelLabel; 
    private JLabel firstLabel; 
    private JTextField firstText; 

    public CopyTextNorthPanel() { 

     setLayout(new GridBagLayout()); 
     GridBagConstraints gbc = new GridBagConstraints(); 
     setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); 
     for (int k = 0; k < 50; k++) { 
      hidelLabel = new JLabel("  "); 
      hidelLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); 
      gbc.fill = GridBagConstraints.HORIZONTAL; 
      gbc.weightx = 0.5; 
      gbc.weighty = 0.5; 
      gbc.gridx = k; 
      gbc.gridy = 0; 
      add(hidelLabel, gbc); 
     } 
     for (int k = 0; k < 5; k++) { 
      firstLabel = new JLabel("Testing Label : ", SwingConstants.RIGHT); 
      firstLabel.setFont(new Font("Serif", Font.BOLD, 20)); 
      firstLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); 
      gbc.fill = GridBagConstraints.HORIZONTAL; 
      gbc.insets = new Insets(0, 0, 5, 0); 
      gbc.gridx = 0; 
      gbc.gridwidth = 8; 
      gbc.gridy = k + 1; 
      add(firstLabel, gbc); 
     } 
     for (int k = 0; k < 5; k++) { 
      firstText = new JTextField("Testing TextField"); 
      firstText.setFont(new Font("Serif", Font.BOLD, 20)); 
      firstText.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); 
      gbc.fill = GridBagConstraints.HORIZONTAL; 
      gbc.insets = new Insets(0, 0, 5, 0); 
      gbc.gridx = 9; 
      gbc.gridwidth = k + 8; 
      gbc.gridy = k + 1; 
      add(firstText, gbc); 
     } 
     for (int k = 0; k < 5; k++) { 
      firstLabel = new JLabel("Testing Label : ", SwingConstants.RIGHT); 
      firstLabel.setFont(new Font("Serif", Font.BOLD, 20)); 
      firstLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); 
      gbc.fill = GridBagConstraints.HORIZONTAL; 
      gbc.insets = new Insets(0, 0, 5, 0); 
      gbc.gridx = 20 + k; 
      gbc.gridwidth = 8; 
      gbc.gridy = k + 1; 
      add(firstLabel, gbc); 
     } 
     for (int k = 0; k < 5; k++) { 
      firstText = new JTextField("Testing TextField"); 
      firstText.setFont(new Font("Serif", Font.BOLD, 20)); 
      firstText.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); 
      gbc.fill = GridBagConstraints.HORIZONTAL; 
      gbc.insets = new Insets(0, 0, 5, 0); 
      gbc.gridx = 29 + k; 
      gbc.gridwidth = 21 - k; 
      gbc.gridy = k + 1; 
      add(firstText, gbc); 
     } 
    } 
}