繁体   English   中英

放大和缩小面板,但滚动条不起作用

[英]Zooming panel in and out but scrollbar don't work

我创建了一个具有放大和缩小功能的面板,但是滚动条不起作用,我的意思是当我放大时无法滚动查看整个面板。
这是我的代码:

import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JScrollPane;
import java.awt.Dimension;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

@SuppressWarnings("serial")
public class PanelWithZoom extends JPanel{

    private JButton btnZoomIn;
    private JButton btnZoomOut;
    private double scale = 1;
    private JPanel innerPanel;
    private JPanel outerPanel;
    public PanelWithZoom() {
        setLayout(new BorderLayout(0, 0));

        JPanel panel = new JPanel();
        add(panel, BorderLayout.NORTH);

        btnZoomIn = new JButton("zoom in");
        btnZoomIn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                scale = scale + 0.1;
                outerPanel.repaint();
                outerPanel.revalidate();
            }
        });
        panel.add(btnZoomIn);

        btnZoomOut = new JButton("zoom out");
        btnZoomOut.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                scale = scale - 0.1;
                outerPanel.repaint();
                outerPanel.revalidate();
            }
        });
        panel.add(btnZoomOut);

        JPanel panel_1 = new JPanel();
        add(panel_1, BorderLayout.WEST);

        JPanel panel_2 = new JPanel();
        add(panel_2, BorderLayout.SOUTH);

        JPanel panel_3 = new JPanel();
        add(panel_3, BorderLayout.EAST);

        outerPanel = new JPanel(){
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);

                Graphics2D g2 = (Graphics2D) g;             
                int w = (int) getWidth();
                int h = (int) getHeight();
                // Translate used to make sure scale is centered
                g2.translate(w/2, h/2);
                g2.scale(scale, scale);
                g2.translate(-w/2, -h/2);
            }


        };
        JScrollPane scroll = new JScrollPane(outerPanel);
        add(scroll, BorderLayout.CENTER);

        innerPanel = new JPanel(){
            @Override
            protected void paintComponent(Graphics g) {
                Graphics2D g2 = (Graphics2D) g;             
                g2.setColor(Color.white);
                g2.fillRect(0, 0, getWidth(), getHeight());
                g2.setColor(Color.black);
                g2.drawString("String for test", 10, 50);
                g2.drawRect(0, 0, getWidth()-1, getHeight()-1);
                setPreferredSize(new Dimension(595, 842));
            }

        };

        outerPanel.add(innerPanel);
    }


    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setContentPane(new PanelWithZoom());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setVisible(true);
    }

}

您可以对其进行测试以了解我的意思。

重写组件的getPreferredSize方法,根据组件的scale和原始大小返回组件的大小。

因为您想对子组件应用缩放,所以您可能希望覆盖paint而不是paintComponent

outerPanel = new JPanel(){
    @Override
    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g.create();             
        g2.scale(scale, scale);
        super.paint(g);
        g2.dispose()
    }
}    

但是,Swing组件可以独立于其父容器进行绘制,这意味着在paint子组件时可能不会调用paint方法。

这样做的问题是,它不会缩放鼠标事件(或其他一系列属性)。

随着问题的不断安装列表,更好的解决方案是使用像JXLayer,这表现在这里

旁注:

  • 使用Graphics#create复制Graphics上下文和Graphics#dispose的属性,在处理翻译/转换/渲染提示和其他属性时更安全,因为对副本的任何更改都不会影响原始属性
  • 不要在任何可能直接或间接导致重画事件触发的paint方法中调用任何方法,您将陷入一个讨厌的永无休止的循环中,这最终将占用您的CPU

Graphics#create和#Dispose示例...

outerPanel = new JPanel(){
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2 = (Graphics2D) g.create();             
        int w = (int) getWidth();
        int h = (int) getHeight();
        // Translate used to make sure scale is centered
        g2.translate(w/2, h/2);
        g2.scale(scale, scale);
        g2.translate(-w/2, -h/2);
        g2.dispose();
    }
}    

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM