1

我试图在 Swing 中绘制一个图表,在大量嵌套的 JPanel 中包含大量(数千个)JLabel,所有这些 JLabel 都具有不同的布局。

我使整个图表可缩放,缩放一个步骤,我在图表中的所有组件上使用 setPrefferedSize()。

它也是交互式的,通过单击其中一个 JLabel,程序会放大该 JLabel。每个 JLabel 都有一个工具提示,并且在悬停时会改变颜色。

问题是当图表太大时,缩放速度太慢了。有一个 for 循环必须遍历图中的所有 JComponent 并更改它们的首选大小。然后我必须在 JComponents 父级上调用 .revalidate() 。

所以我的问题是:

  1. 我是否应该只使用一个具有空布局的 JPanel 并在所有 JLabel 上使用 setBounds() 来定位和放大它们,而不是使用具有不同布局的嵌套 JPanel 来定位和放大它们?电脑会不会更轻?

  2. 我应该使用另一个 GUI 吗?它必须支持以下内容:

    • 绘制带有tooltips的矩形标签,可以添加mouseListener。
    • 可缩放,可以缩放整个图表
    • 可以在图表中绘制文字。
    • 可滚动,可以将图表添加到 JScrollPane(放大时很重要)
4

1 回答 1

2

paintComponent您可以忘记单独的 JLabels,只在主 JPanel的方法中绘制文本项。
您可以使用drawString来绘制文本项目。
此外,您可以保留“缩放级别”值并根据该缩放级别在不同的位置/大小绘制字符串。

如果我是你,我会举一个简单的例子来绘制几千个字符串,看看这在你的目标规范客户端机器上是否足够快。

编辑:像这样的东西:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

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

/**
 * TestPaintComponentZooming
 * 
 * @author davidf
 */
public class TestPaintComponentZooming {
    private JFrame f;
    private JPanel panel;
    private double zoom = 1.0;

    public static void main(String[] args) {
        TestPaintComponentZooming t = new TestPaintComponentZooming();
        t.init();
    }

    public TestPaintComponentZooming() {
    }

    public void init() {
        JButton b = new JButton();
        b.setBackground(Color.red);
        b.setBorder(new LineBorder(Color.black, 2));
        b.setPreferredSize(new Dimension(600, 10));
        panel = new _JPanel();
        panel.add(b);
        f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(panel, "Center");
        f.add(getCheckBoxPanel(), "South");
        f.setLocation(200, 200);
        f.setSize(400, 400);
        f.validate();
        f.setVisible(true);
    }

    private JPanel getCheckBoxPanel() {
        JButton zoomIn = new JButton("Zoom in");
        zoomIn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                zoomAndRepaint(0.1);
            }
        });
        JButton zoomOut = new JButton("Zoom out");
        zoomOut.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                zoomAndRepaint(-0.1);
            }
        });
        JPanel panel2 = new JPanel();
        panel2.add(zoomIn);
        panel2.add(zoomOut);
        return panel2;
    }

    /**
     * zoomAndRepaint
     */
    protected void zoomAndRepaint(double d) {
        zoom += d;
        f.repaint();
    }

    private class _JPanel extends JPanel {

        public _JPanel() {
            super(null);
        }

        /**
         * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
         */
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);


            g.setFont(new Font("Arial", Font.PLAIN, (int) (zoom * 10 + 2)));
            for (int x=0; x < 100; x++) {
                for (int y=0; y < 100; y++) {
                    g.drawString("Hello " + x + "," + y, (int) (x * 60 * zoom), (int) (y * 10 * zoom));                    
                }
            }
        }
    }
}
于 2012-07-18T08:08:27.273 回答