如何在我的gui中绘制确切的行数?

时间:2014-07-24 08:43:10

标签: java swing user-interface paintcomponent

我正在尝试在我的gui中绘制确切的行数。所以我使用TableModelListener来监听我的Jtable中的行数,每次在表中添加新行时,我都会显示行数。

问题:但是现在,当我在jtable中有x行时,我想在我的gui中绘制x行。我试着像上面那样放一个TableModelListerner,但是它没有用。

感谢您的帮助。我很抱歉要上很多课程,但我也想学习制作可重复使用的代码并学习java swing。

enter image description here

课程测试

import java.awt.GridLayout;

import javax.swing.JFrame;

public class Test {

    public static void main(String[] args) {
        JFrame f = new JFrame();

        f.setLayout(new GridLayout(1, 2, 5, 5));

        TablePanel tablePanel = new TablePanel();
        ButtonPanel buttonPanel = new ButtonPanel();
        DrawTwoSameDrawPanel drawPanels = new DrawTwoSameDrawPanel();

        f.add(tablePanel);
        f.add(buttonPanel);
        f.add(drawPanels);

        f.setSize(800, 300);
        f.setLocationRelativeTo(null);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);

    }

}

类MyTableModel

import javax.swing.table.AbstractTableModel;

public class MyTableModel extends AbstractTableModel {

    private String[] columnNames = { "RowListener", "B", "C" };
    private Object[][] data = { { "x", "xx", "xxx" }, { "y", "yy", "yyy" }, { "z", "zz", "zzz" } };

    @Override
    public int getColumnCount() {
        return columnNames.length;
    }

    @Override
    public int getRowCount() {
        return data.length;
    }

    @Override
    public Object getValueAt(int row, int col) {
        return data[row][col];
    }

    @Override
    public Class<?> getColumnClass(int col) {
        return data[0][col].getClass();
    }

    @Override
    public String getColumnName(int col) {
        return columnNames[col];
    }

    @Override
    public void setValueAt(Object aValue, int row, int col) {
        data[row][col] = aValue;
        fireTableStructureChanged();
    }

    public void addRow(Object[][] data) {
        int index = 0;
        int nbRow = this.getRowCount();
        int nbCol = this.getColumnCount();

        Object temp[][] = this.data;
        this.data = new Object[nbRow + 1][nbCol];

        for (Object[] value : temp)
            this.data[index++] = value;

        this.data[index] = data;
        temp = null;

        this.fireTableDataChanged();

    }

}

类ButtonPanel

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;

public class ButtonPanel extends JPanel {

    private JButton button;
    private DrawPanel drawPanel;

    public ButtonPanel() {
        super();

        this.setBorder(new LineBorder(Color.red));
        button = new JButton("Update");
        this.add(button);
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                System.out.println("hello console");

                int n = JOptionPane.showConfirmDialog(null, "Would you like to update drawPanel ?", "Question",
                        JOptionPane.YES_NO_OPTION);

                if (n == JOptionPane.YES_OPTION) {
                    System.out.println("console : YES");
                    updatePanels();
                }
                else
                    System.out.println("console : NO");
            }

        });
    }

    public void updatePanels() {
        drawPanel = new DrawPanel();        
        drawPanel.revalidate();
        drawPanel.repaint();

    }
}

类DrawPanel

public class DrawPanel extends JPanel implements TableModelListener{

    private MyTableModel model = new MyTableModel();
    private JTable table = new JTable(model);

    private int numberOfLine = 0;

    public DrawPanel() {
        super();
        this.setBorder(new LineBorder(Color.blue));
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics graphics = g.create();
        int y = 10;

        /////////don't work 
        RowListener rowListener = new RowListener(model);
        numberOfLine = rowListener.getNumberOfRow();
        //////////

        for (int i = 0; i < numberOfLine; i++) {
            graphics.drawLine(10, y, getWidth() - 10, y);
            y += 10;
        }
        graphics.dispose();
    }

    public void setNumberOfArrows(int arrows) {
        numberOfLine = arrows;
        repaint();
    }

    public int getNumberOfArrows() {
        return numberOfLine;
    }

    @Override
    public Dimension getPreferredSize() {
        return isPreferredSizeSet() ? super.getPreferredSize() : new Dimension(200, 200);
    }

     @Override
     public void tableChanged(TableModelEvent arg0) {
     int numberOfRow = model.getRowCount();
     this.setNumberOfArrows(numberOfRow);
     System.out.println("numberOfRow: " + numberOfRow);

     }

    class RowListener implements TableModelListener {
        private MyTableModel model;
        private int numberOfRow;

        public RowListener(MyTableModel model) {
            this.model = model;
            model.addTableModelListener(this);
        }

        @Override
        public void tableChanged(TableModelEvent arg0) {
            numberOfRow = model.getRowCount();          
            System.out.println("numberOfRow: " + numberOfRow);
        }

        public int getNumberOfRow() {
            return numberOfRow;
        }

        public void setNumberOfRow(int numberOfRow) {
            this.numberOfRow = numberOfRow;
        }
    }

}

类TablePanel

public class TablePanel extends JPanel {

private MyTableModel model = new MyTableModel();
private JTable table = new JTable(model);
private int nbRow = 0;

private JButton addButton = new JButton("Add Row");

public TablePanel() {
    super();
    this.setBorder(new LineBorder(Color.orange));
    this.add(table);
    this.add(addButton);

    addButton.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            model.addRow(new Object[][] { { "u", "u", "u" }, { "v", "v", "vy" }, { "w", "w", "w" } });
            model.fireTableStructureChanged();
            nbRow = model.getRowCount();
            System.out.println("nbRow: " + nbRow);

        }
    });

    this.add(createDisplayNbRowPanel());

}

public JPanel createDisplayNbRowPanel() {
    JPanel p = new JPanel();
    p.add(new JLabel("number of row : "));
    NbRowView nbRowView = new NbRowView(model);
    p.add(nbRowView);
    p.setBorder(new LineBorder(Color.red));

    return p;
}

public int getNbRow() {
    return nbRow;
}

public void setNbRow(int nbRow) {
    this.nbRow = nbRow;
}

class NbRowView extends JLabel implements TableModelListener {

    private MyTableModel model;

    public NbRowView(MyTableModel model) {
        this.model = model;
        model.addTableModelListener(this);
    }

    @Override
    public void tableChanged(TableModelEvent arg0) {
        int nbOfRow = model.getRowCount();
        this.setText(nbOfRow + "");
        DrawPanel drawPanel = new DrawPanel();
        drawPanel.setNumberOfArrows(nbOfRow);

    }

}

}

类DrawTwoSameDrawPanel

public class DrawTwoSameDrawPanel extends JPanel {

private DrawPanel drawPanel_1 = new DrawPanel();
private DrawPanel drawPanel_2 = new DrawPanel();

public DrawTwoSameDrawPanel() {
    super();
    this.setBorder(new LineBorder(Color.green));
    this.add(drawPanel_1);
    this.add(drawPanel_2);
}

}

1 个答案:

答案 0 :(得分:2)

  

当我的jtable中有x行时,我想在我的gui中绘制x行。

查看上一个问题:How to synchronize two view in Java Swing您已经很好地实现了paintComponent()的{​​{1}}方法,但仍需要将其与表模型分离。正如其他开发人员所说,您的代码庞大而复杂,您需要更好地组织它:

  1. 创建一个可重复使用的面板,如this answer
  2. 所示
  3. 当您创建表格模型的新实例时,请附加一个新的TableModelListener来调用DrawPanel方法,该方法会根据您的需要重新绘制您的面板。
  4. 例如:

    setNumberOfArrows()

    注意: Java提供了一种很好的机制来避免创建过多的类来实现接口或从其他类扩展:Anonymous Classes

    关于您的桌面型号,请注意它看起来很像DefaultTableModel,所以您可能想要使用该类而不是创建自己的类(如果它符合您的要求)。

    另外,getColumnClass()方法的实现永远不应该查找数据来检索值,您应该能够返回正确的类,因为您知道表模型将包含哪种数据。

    最后,您的class GuiClass { private DrawPanel drawPanel; public void createAndShowGui() { drawPanel = new DrawPanel(); MyTableModel model = new MyTableModel(); model.addTableModelListener(new TableModelListener() { // Anonymous class @Override public void tableChanged(TableModelEvent e) { if(e.getType() == TableModelEvent.INSERT || e.getType() == TableModelEvent.DELETE) { int rows = ((TableModel)e.getSource()).getRowCount(); drawPanel.setNumberOfArrows(rows); } } }); // rest of your GUI code here } } 方法没有意义,因为您可能希望向表模型添加单行,而不是行和列。我认为它应该是addRow(Object[][] row)(注意单维数组作为参数)。说完之后它应该是这样的:

    addRow(Object[] row)

    请参阅AbstractTableModel API