View Jtable on multiple panels

Asked

Viewed 224 times

1

How do I make mine JTable is displayed on all tabs inside the panels? I’m only able to display in 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);
    }
}
  • I would like it to be the same table for practicality, so that my code is not so extensive, but the important thing is that it appears in all guides

  • So why not add the table in the other panels? If not add, it will not even appear.

  • I already tried, but then the table keeps appearing only in one of the guides. When I add it to all the panels, it is shown only in the "Day 25" tab, it is as if the table were jumping from panel to panel until the last, which in this case is the "Day 25" tab. Will the only solution is to create a table for each panel?

  • 1

    Why are you using absolute layout? It’s getting in the way

  • to be able to position the components freely

  • 1

    Bad idea this, should avoid using absolute layout, unless you have some need and know well what you are doing. He is the one who is resulting this problem of his code. Can I suggest something without this absolute layout? If you are giving problem, you have to remove and try to learn in the most practical and less complicated way.

  • I’m using the absolute layout to be able to have more control over the components and position where I want, because in the other layouts the definitions of positions are already defined, I do not work very well, but suggests me something else please, I need to solve this problem

  • See the answer below. I recommend that you visit and read the links, they will be important for your learning.

Show 3 more comments

1 answer

1


I would like to make two suggestions before:

Avoid using absolute layout, unless it is of extreme necessity and you know the consequences of it, because absolute layout makes it difficult to maintain the interface and makes your application look different depending on the monitor and resolution that is running.

There are several layouts so you don’t have to worry about positioning or manually organizing components. Not to mention that using layouts makes your code easier to maintain than inserting a lot of setbounds, and if you need to change the position of any component, in the absolute layout, you will have to reposition all manually.


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


Besides you have only added in one panel, even adding in several would not be possible the way you are doing, because each component can only be added once in another, so the component will be part of the last container to which added.

To solve, you need to create multiple tables and JSCrollPanes, and share only the TableModel, which is who manages the data in the table. Thus the 3 tables, even though they are distinct, will share the same data.

To decrease code repetition I created a method that receives a TableModel and return a JScrollPane already with defined size and a table filled with the TableModel passed as argument.

I also removed the absolute layout to demonstrate that it is possible to do the same thing without it and in a much more simplified way, just try to understand how the 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));
    }
}

Upshot:

inserir a descrição da imagem aqui

  • thank you so much! I just learned a lot of things I had no idea. Thank you for your attention

  • @Rogériosimsen glad he helped you. You can accept the answer by clicking on v on the left, to serve as reference for others with similar problem.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.