简体   繁体   English

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

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

I have created a panel with zoom in and out function but the scrollbar don't work, I mean when I zoom in I can't scroll to see the entire panel. 我创建了一个具有放大和缩小功能的面板,但是滚动条不起作用,我的意思是当我放大时无法滚动查看整个面板。
This is my code: 这是我的代码:

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);
    }

}

you can test it to understand what I mean. 您可以对其进行测试以了解我的意思。

Override the getPreferredSize method of your component, return the size of the component based on the scale and original size of the component. 重写组件的getPreferredSize方法,根据组件的scale和原始大小返回组件的大小。

Because you want to apply scaling to the child components, you will probably want to override paint instead of paintComponent 因为您想对子组件应用缩放,所以您可能希望覆盖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()
    }
}    

BUT, Swing components can be painted independently of their parent containers, meaning the the paint method may not be called when the child component is painted... 但是,Swing组件可以独立于其父容器进行绘制,这意味着在paint子组件时可能不会调用paint方法。

The problem with this is, it won't scale the mouse events (or a bunch of other properties). 这样做的问题是,它不会缩放鼠标事件(或其他一系列属性)。

With an ever mounting list of issues, a better solution is to use something like JXLayer, as demonstrated here 随着问题的不断安装列表,更好的解决方案是使用像JXLayer,这表现在这里

Side notes: 旁注:

  • Use Graphics#create to copy the properties of the Graphics context and Graphics#dispose , it's safer when dealing with translation/transformations/rendering hints and bunch of other properties, as any changes to the copy won't effect the original 使用Graphics#create复制Graphics上下文和Graphics#dispose的属性,在处理翻译/转换/渲染提示和其他属性时更安全,因为对副本的任何更改都不会影响原始属性
  • Don't call any method from within any paint method which might directly or indirectly cause a repaint event to be triggered, you'll end up in a nasty never ending loop which will eventually consume your CPU 不要在任何可能直接或间接导致重画事件触发的paint方法中调用任何方法,您将陷入一个讨厌的永无休止的循环中,这最终将占用您的CPU

Graphics#create and #Dispose example... 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