سؤال

لقد قمت بإنشاء مصدر المثال التالي وأتساءل عما يجب علي فعله لتحديث JPanel الخاص بي باستخدام JLabel الذي يحتوي على المعلومات الموجودة من الصف الذي تم النقر عليه في JTable.

أردت أيضًا أن أشير إلى أن هذا مجرد مثال حيث قمت بتحسين نموذج التعليمات البرمجية قليلاً بفضل عدد قليل من أعضاء SO هنا.لذلك أقوم بنشر هذا المثال كوسيلة للتعلم

اختبار التأرجح (الرئيسي)

public class SwingTesting {

    private final JFrame frame;
    private final TablePane tablePane;
    private final JSplitPane splitPane;
    private final JPanel infoPanel;
    private final JLabel infoLabel;

    public SwingTesting() {
        tablePane = new TablePane();
        infoPanel = new JPanel();
        frame = new JFrame();

        infoLabel = new JLabel();    //this is the panel i want to add the label to
        infoPanel.add(infoLabel);

        splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, tablePane, infoPanel);

        frame.add(splitPane);
        frame.pack();
        frame.setVisible(true);
    }

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

TablePane

public class TablePane extends JPanel {

    private final JTable table;
    private final TableModel tableModel;
    private final ListSelectionModel listSelectionModel;

    public TablePane() {
        table = new JTable();
        tableModel = createTableModel();
        table.setModel(tableModel);
        table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
        table.add(table.getTableHeader(), BorderLayout.PAGE_START);
        table.setFillsViewportHeight(true); 

        listSelectionModel = table.getSelectionModel();
        table.setSelectionModel(listSelectionModel);
        listSelectionModel.addListSelectionListener(new SharedListSelectionHandler());
        table.setSelectionModel(listSelectionModel);

        this.setLayout(new GridBagLayout());

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.anchor = GridBagConstraints.NORTHWEST;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridheight = 1;
        gbc.gridwidth = 3;
        gbc.insets = new Insets(5, 5, 5, 5);
        gbc.ipadx = 2;
        gbc.ipady = 2;
        gbc.weightx = 1;
        gbc.weighty = 1;

        this.add(new JScrollPane(table), gbc);
    }

    private TableModel createTableModel() {
        DefaultTableModel model = new DefaultTableModel(
            new Object[] {"Car", "Color", "Year"}, 0 
        ){
            @Override public boolean isCellEditable(int row, int column) {
                return false;
            }
        };

        addTableData(model);
        return model;
    }

    private void addTableData(DefaultTableModel model) {
        model.addRow(new Object[] {"Nissan", "Black", "2007"});
        model.addRow(new Object[] {"Toyota", "Blue", "2012"});
        model.addRow(new Object[] {"Chevrolet", "Red", "2009"});
        model.addRow(new Object[] {"Scion", "Silver", "2005"});
        model.addRow(new Object[] {"Cadilac", "Grey", "2001"});
    }


    class SharedListSelectionHandler implements ListSelectionListener {

        //When selection changes i want to add a label to the panel
        //currently it just prints out the info from the selected row    
        @Override
        public void valueChanged(ListSelectionEvent e) {
            ListSelectionModel lsm = (ListSelectionModel) e.getSource();
            String contents = "";

            if(lsm.isSelectionEmpty()) {
                System.out.println("<none>");
            } else {
                int minIndex = lsm.getMinSelectionIndex();
                int maxIndex = lsm.getMaxSelectionIndex();
                for(int i = minIndex; i <= maxIndex; i++) {
                    if(lsm.isSelectedIndex(i)) {
                        for(int j = 0; j < table.getColumnCount(); j++) {
                            contents += table.getValueAt(i, j) + " ";
                        }
                    }
                }
                System.out.println(contents);
            }
        }        
    }
}

لذلك أتساءل عن كيفية الوصول إلى JPanel من ListSelectionListener.هل يجب عليّ فقط تمرير اللوحة إلى فئة TablePane؟أم أن هناك طريقة أكثر ملاءمة للقيام بذلك؟

أيضًا، يقوم ListSelectionListener الخاص بي بطباعة معلومات الصف مرتين لسبب ما، هل أفسدت الحلقة؟

يحرر

public class TablePane extends JPanel {

    private final JTable table;
    private final TableModel tableModel;
    private final ListSelectionModel listSelectionModel;

    private final displayPanel;

    public TablePane() {
        //removed code for reading purposes
    }

    //IDE says issue with thinking displayPanel may have already been initialized
    public TablePane(JPanel panel) {
        //this();
        //displayPanel = panel;
    }


    //ListSelectionListener uses panel.add(jlabel)

}

هل الأمر بهذه البساطة final عن؟

هل كانت مفيدة؟

المحلول

يمكنك تمرير JLabel يعترض على TablePane كائن (في TablePaneمنشئ أو عن طريق توفير مخصص setLabel() طريقة).ثم يمكنك استخدام StringBuilder لإنشاء النص الذي يحتاج للذهاب على التسمية، والاتصال setText() على الملصق بموافقة StringBuilder كائن (من خلال toString() طريقة).

أعتقد أنك تقوم بطباعة كل شيء مرتين لأن valueChanged يتم استدعاء الطريقة مرتين:مرة واحدة عند الإشعار الخاص بإلغاء تحديد الصف الحالي، ثم مرة أخرى عند الإشعار الخاص باختيار الصف الجديد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top