2016-12-25 3 views
1

Я делаю приложение, в котором я хочу добавить текстовые поля в область прокрутки, используя GridBagLayout, и проблема, с которой сталкивается, заключается в том, что первое текстовое поле, которое я добавляю, добавляется вверху панель внутри панели прокрутки, а затем, со второй на, они добавляются в центре, это мой код:gridbaglayout, ставя второй элемент в центр

public class main extends javax.swing.JFrame { 
private static HashMap<String, Integer> anch_codes = new HashMap<String, Integer>(); 
private static List<Component> items = new ArrayList<>(); 
/** 
* Creates new form main 

*/ 
public main() { 
    initComponents(); 
} 
/** 
* This method is called from within the constructor to initialize the form. 
* WARNING: Do NOT modify this code. The content of this method is always 
* regenerated by the Form Editor. 
*/ 
@SuppressWarnings("unchecked") 
// <editor-fold defaultstate="collapsed" desc="Generated Code">       
private void initComponents() { 

    jMenuBar1 = new javax.swing.JMenuBar(); 
    jMenu1 = new javax.swing.JMenu(); 
    jMenuItem1 = new javax.swing.JMenuItem(); 
    jMenu2 = new javax.swing.JMenu(); 

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 

    jMenu1.setText("File"); 

    jMenuItem1.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_MASK)); 
    jMenuItem1.setLabel("Save"); 
    jMenu1.add(jMenuItem1); 
    jMenuItem1.getAccessibleContext().setAccessibleName("save_opt"); 

    jMenuBar1.add(jMenu1); 

    jMenu2.setText("Edit"); 
    jMenuBar1.add(jMenu2); 

    setJMenuBar(jMenuBar1); 

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 
    getContentPane().setLayout(layout); 
    layout.setHorizontalGroup(
     layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
     .addGap(0, 1282, Short.MAX_VALUE) 
    ); 
    layout.setVerticalGroup(
     layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
     .addGap(0, 703, Short.MAX_VALUE) 
    ); 

    pack(); 
}// </editor-fold>       

/** 
* @param args the command line arguments 
*/ 
public static void main(String args[]) { 
    /* Set the Nimbus look and feel */ 
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> 
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. 
    * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
    */ 
    try { 
     for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { 
      if ("Nimbus".equals(info.getName())) { 
       javax.swing.UIManager.setLookAndFeel(info.getClassName()); 
       break; 
      } 
     } 
    } catch (ClassNotFoundException ex) { 
     java.util.logging.Logger.getLogger(main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
    } catch (InstantiationException ex) { 
     java.util.logging.Logger.getLogger(main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
    } catch (IllegalAccessException ex) { 
     java.util.logging.Logger.getLogger(main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
    } catch (javax.swing.UnsupportedLookAndFeelException ex) { 
     java.util.logging.Logger.getLogger(main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
    } 
    //</editor-fold> 

    /* Create and display the form */ 
    java.awt.EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      setAnchCodes(); 
      JFrame fmain = new main(); 

      fmain.setLayout(new GridBagLayout()); 
      GridBagConstraints c = new GridBagConstraints(); 

      fmain.setExtendedState(JFrame.MAXIMIZED_BOTH); 

      JTextField maintext = new JTextField(); 
      addToGrid(c, fmain, maintext, 0, 0, 0.9, 1.0, anch_codes.get("FIRST_LINE_START")); 

      JButton add_btn = new JButton("Add"); 
      addToGrid(c, fmain, add_btn, 1, 0, 0.1, 1.0, anch_codes.get("FIRST_LINE_START")); 

      JPanel scrpanel = new JPanel(new GridBagLayout()); 
      scrpanel.setBackground(Color.WHITE); 
      JScrollPane display_area = new JScrollPane(scrpanel); 
      display_area.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 
      display_area.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); 
      addToGrid(c, fmain, display_area, 0, 1, 1.0, 1000, anch_codes.get("FIRST_LINE_START"), 2); 

      GridBagConstraints an_c = new GridBagConstraints(); 
      eventAddNew(an_c, add_btn,maintext,scrpanel,fmain,display_area); 

      fmain.setVisible(true); 

     } 
    }); 
} 

public static void eventAddNew(GridBagConstraints c, Component ... comp) { 
    JButton add_btn = (JButton) comp[0]; 
    JTextField maintext = (JTextField) comp[1]; 
    JPanel scrpanel = (JPanel) comp[2]; 
    JFrame fmain = (JFrame) comp[3]; 
    JScrollPane display_area = (JScrollPane) comp[4]; 
    add_btn.addActionListener(new java.awt.event.ActionListener() { 
     public void actionPerformed(java.awt.event.ActionEvent evt) { 
      JTextField item = new JTextField(maintext.getText()); 
      item.setEnabled(false); 
      item.setEditable(false); 
      addToGrid(c, scrpanel, item, 0, items.size(), 1.0, 1.0, anch_codes.get("FIRST_LINE_START")); 
      items.add(item); 
      fmain.repaint(); 
      fmain.revalidate(); 
      display_area.repaint(); 
      display_area.revalidate(); 
     } 
    }); 
} 

public static void addToGrid(GridBagConstraints c, Component parent, Component child, int x, int y, double weightx, double weighty, int anchor){ 

    String fcls = parent.getClass().toString(); 
    String cls = fcls.substring(fcls.lastIndexOf(".")+1); 

    c.fill = GridBagConstraints.HORIZONTAL; 
    c.anchor = anchor; 
    c.weightx = weightx; 
    c.weighty = weighty; 
    c.gridx = x; 
    c.gridy = y; 

    if ("JFrame".equals(cls) || "main".equals(cls)) { 
     JFrame frame = (JFrame) parent; 
     frame.add(child,c); 
    } else if ("JPanel".equals(cls)) { 
     JPanel panel = (JPanel) parent; 
     panel.add(child, c); 
    } 
} 

public static void addToGrid(GridBagConstraints c, JFrame frame, Component element, int x, int y, double weightx, double weighty, int anchor, int gridwidth){ 

    String fcls = element.getClass().toString(); 
    String cls = fcls.substring(fcls.lastIndexOf(".")+1); 


    c.anchor = anchor; 
    c.weightx = weightx; 
    c.weighty = weighty; 
    c.gridx = x; 
    c.gridy = y; 
    c.gridwidth = gridwidth; 
    if ("JScrollPane".equals(cls)) { 
     c.fill = GridBagConstraints.BOTH; 
    } else { 
     c.fill = GridBagConstraints.HORIZONTAL; 
    } 
    frame.add(element,c); 
} 

private static void setAnchCodes() { 
    anch_codes.put("FIRST_LINE_START", 23); 
    anch_codes.put("FIRST_LINE_END", 24); 
} 

// Variables declaration - do not modify      
private javax.swing.JMenu jMenu1; 
private javax.swing.JMenu jMenu2; 
private javax.swing.JMenuBar jMenuBar1; 
private javax.swing.JMenuItem jMenuItem1; 
// End of variables declaration     
} 

у меня была та же проблема с внешней рамкой, которая также имеет расположение сумки сетки но я работал над этим, устанавливая весомое значение, но это не работает для рассматриваемого случая и, вероятно, это не правильный способ сделать это. Если кто-нибудь может дать какие-либо советы, это будет очень полезно.

+0

Что именно вы пытаетесь достичь? –

+0

Похоже, вы хотите использовать JList или JTable, а не добавлять нередактируемые JTextFields. –

+0

mmm, возможно, свинг не мой сильный костюм, честно говоря, прошло много лет с тех пор, как я сделал что-то «важное» с ним, в любом случае я хотел бы знать, как положить вещи, где я хочу их с gridbaglayout, так как используя его для большего количества вещей. Спасибо за предложение. –

ответ

2

Для этого вам не нужно использовать GridBagLayout, и я предлагаю, чтобы вы этого не сделали. Вместо этого создайте JPanel, который использует GridLayout(0, 1) для сетки, которая имеет 1 столбец и любое количество строк. Затем - и это ключевое слово - поместите этот JPanel в другой JPanel, который использует BorderLayout, в позицию BorderLayout.PAGE_START, так что он всегда на вершине. Затем поместите этот макет границы - используя JPanel в свой JScrollPane.

Например:

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 

import javax.swing.*; 

public class AddComponents extends JPanel { 
    private static final int PREF_W = 600; 
    private static final int PREF_H = 450; 
    private JTextField inputField = new JTextField(20); 
    private AddAction addAction = new AddAction("Add"); 
    private JButton addButton = new JButton(addAction); 
    private JPanel innerPanel = new JPanel(new GridLayout(0, 1)); // 1 column, any number of rows 

    public AddComponents() { 
     JPanel borderLayoutPanel = new JPanel(new BorderLayout()); 
     borderLayoutPanel.add(innerPanel, BorderLayout.PAGE_START); 
     JScrollPane scrollPane = new JScrollPane(borderLayoutPanel); 
     scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 

     inputField.setAction(addAction); 
     JPanel topPanel = new JPanel(); 
     topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.LINE_AXIS)); 
     topPanel.add(inputField); 
     topPanel.add(addButton); 

     setLayout(new BorderLayout()); 
     add(scrollPane); 
     add(topPanel, BorderLayout.PAGE_START); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     Dimension prefSize = super.getPreferredSize(); 
     if (isPreferredSizeSet()) { 
      return prefSize; 
     } else { 
      int w = Math.max(PREF_W, prefSize.width); 
      int h = Math.max(PREF_H, prefSize.height); 
      return new Dimension(w, h); 
     } 
    } 

    private class AddAction extends AbstractAction { 
     public AddAction(String name) { 
      super(name); 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      String text = inputField.getText(); 
      JTextField innerTextField = new JTextField(text); 
      innerPanel.add(innerTextField); 
      revalidate(); 
      repaint(); 
      inputField.selectAll(); 
      inputField.requestFocusInWindow(); 
     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> createAndShowGui()); 
    } 

    private static void createAndShowGui() { 
     AddComponents mainPanel = new AddComponents(); 
     JFrame frame = new JFrame("Add Components"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(mainPanel); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 
} 

Но показав это, если вы хотите отобразить JTextField эквиваленты, те, которые могут или не могут быть доступны для редактирования, в зависимости от вашего желания, а затем использовать простой JTable вместо этого.

Например:

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.event.ActionEvent; 

import javax.swing.*; 
import javax.swing.table.DefaultTableModel; 

public class AddItems extends JPanel { 
    private static final int PREF_W = 600; 
    private static final int PREF_H = 450; 
    private JTextField inputField = new JTextField(20); 
    private AddToTableAction addAction = new AddToTableAction("Add"); 
    private JButton addButton = new JButton(addAction); 
    private DefaultTableModel tableModel = new DefaultTableModel(new String[]{"A"}, 0); 
    private JTable table = new JTable(tableModel){ 
     public boolean isCellEditable(int row, int column) { 
      return false; 
     }; 
    }; 

    public AddItems() { 
     table.setTableHeader(null); 
     JScrollPane scrollPane = new JScrollPane(table); 
     scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 

     inputField.setAction(addAction); 
     JPanel topPanel = new JPanel(); 
     topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.LINE_AXIS)); 
     topPanel.add(inputField); 
     topPanel.add(addButton); 

     setLayout(new BorderLayout()); 
     add(scrollPane); 
     add(topPanel, BorderLayout.PAGE_START); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     Dimension prefSize = super.getPreferredSize(); 
     if (isPreferredSizeSet()) { 
      return prefSize; 
     } else { 
      int w = Math.max(PREF_W, prefSize.width); 
      int h = Math.max(PREF_H, prefSize.height); 
      return new Dimension(w, h); 
     } 
    } 

    private class AddToTableAction extends AbstractAction { 
     public AddToTableAction(String name) { 
      super(name); 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      String text = inputField.getText(); 
      tableModel.addRow(new String[] {text}); 
      inputField.selectAll(); 
      inputField.requestFocusInWindow(); 
     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> createAndShowGui()); 
    } 

    private static void createAndShowGui() { 
     AddItems mainPanel = new AddItems(); 
     JFrame frame = new JFrame("AddItems"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 
} 
+0

Спасибо! что, играя немного с колонками и строками gridlayout, я точно делаю то, что хочу, я действительно начал делать это таким образом, но не думал добавлять дополнительную панель с макетом границы. –

Смежные вопросы