Display JTable in multiple panels

1

How do I get my JTable displayed on all tabs within the panels? I can only display on the "Day 5" tab.

import java.awt.Container;
import java.sql.ResultSet;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;

public class NewClass extends JFrame{

     ResultSet rst = null;
     public Container content;
     public JPanel jpDespesas, jpGerenciar, jpCofre, jpDia5, jpDia20, jpDia25;
     public JLabel jlTotal, jlTitulo, jlVencimento, jlValor, jlSemana, jlCofre;
     public JTextField jtTotal, jtTitulo, jtVencimento, jtValor, jtSemana;
     public JButton jbCalcular, jbSalvar, jbEditar, jbExcluir, jbTotal, jbCofre;
     public JTable jtbDespesas;
     public JTabbedPane jtb;

    public NewClass() {

        super("Controle financeiro");

        setLayout(null);
        setSize(680, 350);
        setResizable(false);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        content = getContentPane();

        criaTela();

    }

    public void criaTela() {

        //CRIANDO JPANEL PRINCIPAL E SETANDO PROPRIEDADES
        jpDespesas = new JPanel();
        jpDespesas.setLayout(null);
        jpDespesas.setBorder(BorderFactory.createTitledBorder("Resumo mensal"));
        jpDespesas.setBounds(20, 15, 340, 315);
        add(jpDespesas);

        //CRIANDO PAINEL COM ABAS
        jtb = new JTabbedPane();
        jtb.setBounds(15, 20, 310, 145);
        jpDespesas.add(jtb);

        jpDia5 = new JPanel();
        jpDia5.setLayout(null);
        jpDia5.setBounds(20, 20, 100, 170);
        jtb.add("Dia 5", jpDia5);

        jpDia20 = new JPanel();
        jpDia20.setLayout(null);
        jpDia20.setBounds(20, 20, 250, 170);
        jtb.add("Dia 20", jpDia20);

        jpDia25 = new JPanel();
        jpDia25.setLayout(null);
        jpDia25.setBounds(20, 20, 250, 170);
        jtb.add("Dia 25", jpDia25);

        //CRIANDO O JTABLE
        jtbDespesas = new JTable();

        //SETANDO A QUANTIDADE DE COLUNAS E SEUS RESPECTIVOS TÍTULOS
        jtbDespesas.setModel(new DefaultTableModel(new Object[][]{}, new String[]{"Título", "Vencimento", "Valor"}));

        //SETANDO A LARGURA DE CADA COLUNA
        jtbDespesas.getColumnModel().getColumn(0).setPreferredWidth(100);
        jtbDespesas.getColumnModel().getColumn(1).setPreferredWidth(50);
        jtbDespesas.getColumnModel().getColumn(2).setPreferredWidth(50);

        //ADICIONANDO LINHAS
        DefaultTableModel dtm = (DefaultTableModel) jtbDespesas.getModel();
        dtm.addRow(new Object[]{});
        dtm.addRow(new Object[]{});
        dtm.addRow(new Object[]{});
        dtm.addRow(new Object[]{});
        dtm.addRow(new Object[]{});
        dtm.addRow(new Object[]{});
        dtm.addRow(new Object[]{});

        JScrollPane jp = new JScrollPane();
        jp.setBounds(5, 10, 295, 100);
        jp.setViewportView(jtbDespesas);
        jpDia5.add(jp);
    }

    public static void main(String[] args) {
        new NewClass().setVisible(true);
    }
}
    
asked by anonymous 08.04.2018 / 19:10

1 answer

2

I'd like to give you two suggestions first:

  

Avoid using absolute layout unless you are in dire need and know the consequences , since absolute layout makes it difficult to maintain the interface and makes your application look different depending on the monitor and resolution being executed.

     

There are several layouts managers for you to you do not have to worry about manual positioning or organization of components. Not to mention that the use of layouts makes your code easier to maintain than inserting a lot of setbounds , and in case you need to change the position of any component, in the absolute layout, you will have to reposition them all manually.

  

And it's always good to mention which screens should be started within the Event-Dispatch-Thread , because swing is not Thread-Safe , and the entire interface needs to start within this single Thread . In this answer is better explained the reason for this and any problems that may occur. This other answer shows you some ways to start the application within this Thread . p>

In addition to adding only one panel, even adding to many would not be possible the way you are doing, since each component can only be added only once in another, so that the component will only be part of the last < in> container to which it is added.

To resolve, you need to create multiple tables and JSCrollPanes , and only share the TableModel , which manages the table data. So the 3 tables, even if they are different, will share the same data.

To decrease code repetition, I've created a method that gets a TableModel and returns a JScrollPane already defined size and a table filled with TableModel passed as an argument.

I also removed the absolute layout to demonstrate that it is possible to do the same thing without it and in a much simpler way, just try to understand how layouts work and combine them as needed.

See the code:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.sql.ResultSet;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

public class NewClass extends JFrame {

    ResultSet rst = null;
    public JPanel jpDespesas, jpGerenciar, jpCofre, jpDia5, jpDia20, jpDia25;
    public JLabel jlTotal, jlTitulo, jlVencimento, jlValor, jlSemana, jlCofre;
    public JTextField jtTotal, jtTitulo, jtVencimento, jtValor, jtSemana;
    public JButton jbCalcular, jbSalvar, jbEditar, jbExcluir, jbTotal, jbCofre;
    public JTable jtbDespesas;
    public JTabbedPane jtb;

    public NewClass() {

        super("Controle financeiro");

        setPreferredSize(new Dimension(680, 350));
        criaTela();
        setResizable(false);
        pack();
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


    }

    public void criaTela() {

        // CRIANDO JPANEL PRINCIPAL E SETANDO PROPRIEDADES
        jpDespesas = new JPanel(new FlowLayout(FlowLayout.LEFT));
        jpDespesas.setPreferredSize(new Dimension(340, 315));
        jpDespesas.setBorder(BorderFactory.createTitledBorder("Resumo mensal"));
        getContentPane().add(jpDespesas, BorderLayout.CENTER);

        // CRIANDO PAINEL COM ABAS
        jtb = new JTabbedPane();
        jtb.setPreferredSize(new Dimension(340, 315));
        jpDespesas.add(jtb);

        jpDia5 = new JPanel();
        jpDia5.setPreferredSize(new Dimension(100, 170));
        jtb.add("Dia 5", jpDia5);

        jpDia20 = new JPanel();
        jpDia20.setPreferredSize(new Dimension(250, 170));
        jtb.add("Dia 20", jpDia20);

        jpDia25 = new JPanel();
        jpDia25.setPreferredSize(new Dimension(250, 170));
        jtb.add("Dia 25", jpDia25);

        DefaultTableModel dtm = new DefaultTableModel(new Object[][] {}, new String[] { "Título", "Vencimento", "Valor" });
        dtm.addRow(new Object[] {});
        dtm.addRow(new Object[] {});
        dtm.addRow(new Object[] {});
        dtm.addRow(new Object[] {});
        dtm.addRow(new Object[] {});
        dtm.addRow(new Object[] {});
        dtm.addRow(new Object[] {});

        jpDia5.add(getTablePane(dtm));
        jpDia25.add(getTablePane(dtm));
        jpDia20.add(getTablePane(dtm));
    }

    public JScrollPane getTablePane(TableModel model) {

        JTable table = new JTable(model);
        table.getColumnModel().getColumn(0).setPreferredWidth(100);
        table.getColumnModel().getColumn(1).setPreferredWidth(50);
        table.getColumnModel().getColumn(2).setPreferredWidth(50);
        JScrollPane jp = new JScrollPane(table);
        jp.setPreferredSize(new Dimension(295, 100));
        return jp;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new NewClass().setVisible(true));
    }
}

Result:

    
08.04.2018 / 20:53