开发者

Centered JLabel inside JTable

开发者 https://www.devze.com 2023-02-09 06:53 出处:网络
How can I display a centere开发者_开发技巧d text or something similar inside a JTable if there are not results after a query?

How can I display a centere开发者_开发技巧d text or something similar inside a JTable if there are not results after a query? Thank you all.


I wouldn't show a Label inside the JTable, but instead the JTable.

Try removing the table element from its container, and adding the Jlabel with the message.

When the user runs another query, with positive results, do the opposite way (remove the label, add the table)


Just add text to the model as you would noramlly do and then create a custom renderer. Something like:

DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
centerRenderer.setHorizontalAlignment( JLabel.CENTER );
table.getColumnModel().getColumn(???).setCellRenderer( centerRenderer );

Or if you want all columns containing String data to be centered then you can use

table.getDefaultRenderer(class.String);

and then reset the alignment for that renderer.

Edit: I misread the question.

If all you want to do is display a message in the table than you can change the TableModel of the table to just display a single column table with a single row with your error message. This column will still need to use a custom renderer.

To reset the model you just do:

DefaultTableModel model = new DefaultTableModel(...);
table.setModel( model );

Of course if the query is successfull you would also have to reset the model with the new data as well.


Another alternative: really paint some - appropriately positioned - text in the the table instead of the rows if there are no rows. To achieve that

  • subclass J/X/Table and override paintComponent
  • make sure the table is expanded to the viewport size (that is tracksViewportHeight is true, that's the default for JXTable, must be set explicitly for JTable)

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (getRowCount() > 0)
            return;
    
        Component comp = getNoDataRenderer();
        CellRendererPane rendererPane = getRendererPane();
    
        Dimension size = getSize();
        Dimension prefSize = comp.getPreferredSize();
    
        Rectangle rect = new Rectangle((size.width - prefSize.width) / 2,
                size.height / 4, prefSize.width, prefSize.height);
        rendererPane.paintComponent(g, comp, this, rect);
    
    }
    
    private Component getNoDataRenderer() {
        if (noDataRenderer == null) {
            noDataRenderer = createNoDataRenderer();
        }
    String localizedNoData = UIManager.getString("noData");
    Component comp = noDataRenderer.getTableCellRendererComponent(this, 
         localizedNoData != null ? localizedNoData : "No Data Available", 
         false, false, -1, -1);
        Font bigger = getFont().deriveFont(Font.BOLD | Font.ITALIC,
                getFont().getSize2D() * 2);
        comp.setFont(bigger);
        return comp;
    }
    
    private DefaultTableCellRenderer createNoDataRenderer() {
        DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
        renderer.setForeground(Color.GRAY);
        return renderer;
    }
    
    private CellRendererPane getRendererPane() {
        for (int i = 0; i < getComponentCount(); i++) {
            if (getComponent(i) instanceof CellRendererPane) {
                return (CellRendererPane) getComponent(i);
            }
        }
        return null;
    }
    

Advantages over the other suggestions (arguably, these are my 2 cents of course :):

  • switch components (label vs table): kind of discontinous visuals which might confuse users. An empty table is still a table.
  • special empty model: solving a view problem in the data realm is ... suboptimal. Plus special care needs to be taken to not loose the column state of the real model
0

精彩评论

暂无评论...
验证码 换一张
取 消