用户调整大小后停止调整 jpanel 大小
我有一个带有 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
对于以编程方式调整大小的代码将类似于:
即程序控制触发哪些侦听器。
For programmatic resizing the code would be something like:
That is the program is in control of what listener get fired.
@Nate Glenn 按照 @StanislavL 的建议使用 setResisable() 方法(+1)。它将禁用用户调整大小,但您仍然可以通过编程方式调整大小。自己尝试一下,例如将此 main 添加到您的代码中并运行它,您会发现框架的大小将为 200、200,并且您将无法调整其大小。
否则,如果您的问题实际上具有更具体的性质,那么请尝试重新表述您的问题?
@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.
Otherwise if your problem is in fact of a more specific nature then please try and rephrase your question?