用户调整大小后停止调整 jpanel 大小

发布于 2024-11-07 03:12:50 字数 3755 浏览 0 评论 0原文

我有一个带有 JLabel 的 JPanel,它经常加载新图片。我将其编程为在每次加载后调整大小以适应图片。但是,我希望用户能够将面板调整到一定的大小并保持这种状态(当前重新加载时,无法永久调整大小可能会加剧)。但我的代码不起作用:

public class Grapher extends JFrame{        
    private JScrollPane scrollPane;
    private static JPanel topPanel;
    private static JLabel label;
    private static ImageIcon image;

    private static boolean dontResize = false;
    private static boolean firstTime = true;

    public Grapher(){
        setTitle( "some graph" );
        setBackground( Color.gray );
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

        topPanel = new JPanel();
        topPanel.setLayout( new BorderLayout() );
        getContentPane().add( topPanel );
        label = new JLabel();

        scrollPane = new JScrollPane();
        scrollPane.getViewport().add( label );
        topPanel.add( scrollPane, BorderLayout.CENTER );
        topPanel.addComponentListener(new Listeners());
        topPanel.setName("Soar Grapher Panel");
    }

    public void display(String fileName){
        //steal focus the first time an image is displayed
        if(image == null)
            setVisible(true);
        image = new ImageIcon(fileName);
        image.getImage().flush();
        boolean temp = dontResize;
        setSize(getPreferredSize());
        dontResize = temp;
        System.out.println("afterWards: " + dontResize);
        label.setIcon(image);
        label.repaint();
    }

    @Override
    public Dimension getPreferredSize(){
        if(dontResize){
            System.err.println("not resizing!");
            return getSize();
        }
        if (image == null)
            return new Dimension(100,100);
        else
            return new Dimension(image.getIconWidth() > getWidth() + 40 ? image.getIconWidth() + 40 : getWidth(),
                    image.getIconHeight() > getHeight() + 60 ? image.getIconHeight() + 60 : getHeight());
    }

    private class Listeners implements ComponentListener{

            @Override
            public void componentHidden(ComponentEvent arg0) {}

            @Override
            public void componentMoved(ComponentEvent arg0) {}

            @Override
            public void componentResized(ComponentEvent arg0) {
                System.out.println("componentResized: " + dontResize);
                //TODO make it not resize after the user resizes it themselves.
                System.err.println(arg0.getComponent().getName());
                System.err.println("resized!");
                if(!firstTime)
                    dontResize = true;
                firstTime = false;
            }

            @Override
            public void componentShown(ComponentEvent arg0) {}
    }

}

我试图在程序调整大小时保存 dontResize 布尔值,但不幸的是,侦听器似乎在 resize() 函数执行之前激活。如何区分用户调整大小和程序调整大小?

编辑_______ 在程序化调整大小期间删除监听器似乎是正确的方法;然而,除了用户调整大小之外,监听器似乎是在随机时间被调用的,把一切搞乱了。这就是我所拥有的:

private static ComponentListener listeners = new Listeners();
private static boolean resizeOkay = true;
...
[inside the display() function]
    if(resizeOkay){
        removeComponentListener(listeners);
        System.err.println("No handler should be called between here");
        setSize(getPreferredSize());
        System.err.println("and here.");
        addComponentListener(listeners);
    }
    label.setIcon(image);
    label.repaint();
[inside the listener]
@Override
public void componentResized(ComponentEvent arg0) {
    System.err.println("resize handler");
    resizeOkay = false;
}

在没有任何用户调整大小的情况下,上面的代码将打印:

No handler should be called between here
and here.
resize handler
resize handler

它还如何被调用?这可以防止窗口被调整大小。

I have a JPanel with a JLabel which frequently loads a new picture. I programmed it to resize to fit the picture after every load. However, I would for the user to be able to adjust the panel to a certain size and leave it that way (with current reloads the inability to permanently resize can be aggravating). My code doesn't work though:

public class Grapher extends JFrame{        
    private JScrollPane scrollPane;
    private static JPanel topPanel;
    private static JLabel label;
    private static ImageIcon image;

    private static boolean dontResize = false;
    private static boolean firstTime = true;

    public Grapher(){
        setTitle( "some graph" );
        setBackground( Color.gray );
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

        topPanel = new JPanel();
        topPanel.setLayout( new BorderLayout() );
        getContentPane().add( topPanel );
        label = new JLabel();

        scrollPane = new JScrollPane();
        scrollPane.getViewport().add( label );
        topPanel.add( scrollPane, BorderLayout.CENTER );
        topPanel.addComponentListener(new Listeners());
        topPanel.setName("Soar Grapher Panel");
    }

    public void display(String fileName){
        //steal focus the first time an image is displayed
        if(image == null)
            setVisible(true);
        image = new ImageIcon(fileName);
        image.getImage().flush();
        boolean temp = dontResize;
        setSize(getPreferredSize());
        dontResize = temp;
        System.out.println("afterWards: " + dontResize);
        label.setIcon(image);
        label.repaint();
    }

    @Override
    public Dimension getPreferredSize(){
        if(dontResize){
            System.err.println("not resizing!");
            return getSize();
        }
        if (image == null)
            return new Dimension(100,100);
        else
            return new Dimension(image.getIconWidth() > getWidth() + 40 ? image.getIconWidth() + 40 : getWidth(),
                    image.getIconHeight() > getHeight() + 60 ? image.getIconHeight() + 60 : getHeight());
    }

    private class Listeners implements ComponentListener{

            @Override
            public void componentHidden(ComponentEvent arg0) {}

            @Override
            public void componentMoved(ComponentEvent arg0) {}

            @Override
            public void componentResized(ComponentEvent arg0) {
                System.out.println("componentResized: " + dontResize);
                //TODO make it not resize after the user resizes it themselves.
                System.err.println(arg0.getComponent().getName());
                System.err.println("resized!");
                if(!firstTime)
                    dontResize = true;
                firstTime = false;
            }

            @Override
            public void componentShown(ComponentEvent arg0) {}
    }

}

I'm attempting to save the dontResize boolean when the program resizes, but unfortunately the listener seems to activate before the resize() function does. How do I differentiate user resizing from programmatic resizing?

EDIT_______
Removing a listener during the duration of the programmatic resizing seems to be the way to go; however, the listener seems to be called at random times besides the user resizing, messing everything up. This is what I have:

private static ComponentListener listeners = new Listeners();
private static boolean resizeOkay = true;
...
[inside the display() function]
    if(resizeOkay){
        removeComponentListener(listeners);
        System.err.println("No handler should be called between here");
        setSize(getPreferredSize());
        System.err.println("and here.");
        addComponentListener(listeners);
    }
    label.setIcon(image);
    label.repaint();
[inside the listener]
@Override
public void componentResized(ComponentEvent arg0) {
    System.err.println("resize handler");
    resizeOkay = false;
}

Without any user resizing, the above code prints:

No handler should be called between here
and here.
resize handler
resize handler

How else is it being called? This prevents the windows from ever being resized.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

你的心境我的脸 2024-11-14 03:12:50

如何区分用户调整大小和程序调整大小?

对于以编程方式调整大小的代码将类似于:

panel.removeListeners(...);
doPanelResizing();
panel.addListeners();

即程序控制触发哪些侦听器。

How do I differentiate user resizing from programmatic resizing?

For programmatic resizing the code would be something like:

panel.removeListeners(...);
doPanelResizing();
panel.addListeners();

That is the program is in control of what listener get fired.

懵少女 2024-11-14 03:12:50
if (firstTime) {
  setResizable(false);
}
if (firstTime) {
  setResizable(false);
}
风流物 2024-11-14 03:12:50

@Nate Glenn 按照 @StanislavL 的建议使用 setResisable() 方法(+1)。它将禁用用户调整大小,但您仍然可以通过编程方式调整大小。自己尝试一下,例如将此 main 添加到您的代码中并运行它,您会发现框架的大小将为 200、200,并且您将无法调整其大小。

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {           
                JFrame f = new Grapher();
                f.setSize(400, 300);
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setResizable(false);
                f.setSize(200,200);
                f.setVisible(true);
            }
        });
    }

否则,如果您的问题实际上具有更具体的性质,那么请尝试重新表述您的问题?

@Nate Glenn Use setResisable() method as @StanislavL 's suggests (+1). It will disable user resizing, while you can still resize programmatically. Try it yourself,e.g. add this main to your code and run it see that the frame will have size of 200, 200 and you will not be able to resize it.

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {           
                JFrame f = new Grapher();
                f.setSize(400, 300);
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setResizable(false);
                f.setSize(200,200);
                f.setVisible(true);
            }
        });
    }

Otherwise if your problem is in fact of a more specific nature then please try and rephrase your question?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文