【问题标题】:Jtable with a custom layout is flickering when the user scrolls it具有自定义布局的 Jtable 在用户滚动时闪烁
【发布时间】:2014-06-22 05:20:02
【问题描述】:

我已经做了一个扩展 JTable 的自定义表格。我的自定义表格的布局不同,它有一个 JPanel,表格底部有一个按钮。 无论滚动位置如何,面板都应始终位于表格可见部分的底部。

它几乎可以按我的意愿工作,只是滚动表格时它会闪烁面板后面有一些行

是否有可能以某种方式使代码变得更好,以消除闪烁并使其面板后面没有行?

这是我的自定义表格的一个工作示例:

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;

class TableDemo {
    public static void main(String[]args){
          new TableDemo();
    }

    public TableDemo() {
        JFrame frame = new JFrame();
        frame.setLayout(new BorderLayout());
        CustomTable table = new CustomTable();
        JScrollPane scrollPane = new JScrollPane();
        scrollPane.setViewportView(table);
        table.initChangeListener();
        frame.add(scrollPane);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    class CustomTable extends JTable {
        private TableLayout layout = new TableLayout();
        public CustomTable() {
            super(100,10);
            JPanel panel = new JPanel();
            panel.setLayout(new FlowLayout(FlowLayout.CENTER));
            panel.setBackground(Color.lightGray);
            panel.add(new JButton("Press me!"));
            this.add(panel);
            this.setLayout(layout);
        }

        public void initChangeListener() {
            if(this.getParent() != null) {
                if(this.getParent() instanceof JViewport) {
                    JViewport viewport = (JViewport)this.getParent();
                    viewport.addChangeListener(new ChangeListener() {
                        @Override
                        public void stateChanged(ChangeEvent e) {
                            if(CustomTable.this.getLayout() instanceof TableLayout) {
                                CustomTable.this.getLayout().layoutContainer(CustomTable.this);
                            }
                        }
                    });
                }
            }
        }
    }

    class TableLayout implements LayoutManager {

        @Override
        public void addLayoutComponent(String name, Component comp) {}

        @Override
        public void removeLayoutComponent(Component comp) {}

        @Override
        public Dimension preferredLayoutSize(Container parent) {
            return parent.getPreferredSize();
        }

        @Override
        public Dimension minimumLayoutSize(Container parent) {
            return parent.getMinimumSize();
        }


        @Override
        public void layoutContainer(Container parent) {
            CustomTable table = (CustomTable)parent;
            JViewport vp = (JViewport)table.getParent();
            Point p = vp.getViewPosition();
            Rectangle rectangle = vp.getVisibleRect();

            for(Component c : parent.getComponents()) {
                if(c instanceof JPanel) {
                    c.setBounds(0,  p.y + (int)rectangle.getHeight() - 40, (int)rectangle.getWidth(), (int)rectangle.getHeight());
                }
            }
        }
    }
}

【问题讨论】:

  • 1.让鲸鱼的 JViewport,将 LayoutManager 应用于其父级,应用于 JScrollPane,2. JTable 无法返回合理的 PreferredSize,为 JScrollPanes 子级覆盖 etPreferredScrollableViewportSize,3. setBounds 方法错误,可以完全扼杀善意
  • 为什么不使用单独的组件?

标签: java swing layout jtable flicker


【解决方案1】:

为什么要使用自定义布局?它有什么特殊用途吗?如果不是,我想我有其他建议

您可以通过扩展 JPanel(或 JComponent)而不是扩展 JTable 来创建新组件,并且可以将带有滚动窗格和按钮面板的 JTable 添加到该容器。请看下面的代码。

import java.awt.BorderLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;

class TableDemo {
public static void main(String[]args){
      new TableDemo();
}

public TableDemo() {
    JFrame frame = new JFrame();
    frame.setLayout(new BorderLayout());
    CustomTable table = new CustomTable();
    frame.add(table);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
}


class CustomTable extends JPanel
{

    JTable table;
    JPanel buttonPanel;

    public CustomTable() {
        super();
        setLayout(new BorderLayout());
        table=new JTable(100,10);
        JScrollPane scrollPane=new JScrollPane(table);
        buttonPanel=new JPanel();
        buttonPanel.add(new JButton("Press Me"));

        add(scrollPane, BorderLayout.CENTER);
        add(buttonPanel, BorderLayout.SOUTH);
    }
}
}

【讨论】:

    猜你喜欢
    • 2015-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-17
    • 2018-06-20
    相关资源
    最近更新 更多