gpt4 book ai didi

java - 单击按钮打开时,新 JFrame 以禁用状态打开

转载 作者:搜寻专家 更新时间:2023-11-01 03:47:58 24 4
gpt4 key购买 nike

我遇到了一个非常不寻常的情况。我有一个类“ScreenSizeSelector”,它有一个方法“getSelectedScreenSize”。该方法的工作是创建一个 UI,用户拖动 UI 和方法返回窗口大小。

现在我通过以下方式调用类的方法:

  1. 一个简单的类(非 GUI)
  2. 在按钮上从 JFrame 单击

在第一种情况下,它工作得很好(即大小选择器窗口打开,用户拖动它,调整它的大小并返回窗口坐标)但在第二种情况下,窗口打开但处于禁用模式,用户无法无法在窗口上执行任何操作,甚至无法关闭窗口。

这是我使用的代码

屏幕尺寸选择器类:

package screenrecorder;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.Border;


class ScreenSizeSelector {

private JFrame sizeSelectorWindow;
private JButton btnOk;
private Border emptyBorder;
private Rectangle screenArea = null;
private static Object lock = new Object();



public Rectangle getSelectedScreenSize(){

screenSizeSelectorUI();

Thread t = new Thread() {
public void run() {
synchronized(lock) {
while (sizeSelectorWindow.isVisible())
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};

t.start();
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}

return screenArea;
}


public void screenSizeSelectorUI() {
emptyBorder = BorderFactory.createEmptyBorder();

sizeSelectorWindow = new JFrame("Select screen area");

btnOk = new JButton("Start");
sizeSelectorWindow.setUndecorated(true);
sizeSelectorWindow.getRootPane().setWindowDecorationStyle(3);
sizeSelectorWindow.setBackground( new Color(0, 0, 0, 0) );
sizeSelectorWindow.setSize(400,400);

sizeSelectorWindow.addWindowListener(new WindowEventHandler());
sizeSelectorWindow.setAlwaysOnTop(true);
sizeSelectorWindow.setLocationRelativeTo(null);


btnOk.setToolTipText("Click this button after deciding the screen area");
btnOk.addActionListener(new ButtonEventHandler());


JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
buttonPanel.setBackground(new Color(0,0,0,0));
buttonPanel.add(btnOk);
sizeSelectorWindow.add(buttonPanel,BorderLayout.SOUTH);

sizeSelectorWindow.setVisible(true);
sizeSelectorWindow.setEnabled(true);

}

class ButtonEventHandler implements ActionListener {

@Override
public void actionPerformed(ActionEvent e) {

int x = (int)(sizeSelectorWindow.getBounds().getX());
int y = (int) (sizeSelectorWindow.getBounds().getY());
int width = sizeSelectorWindow.getWidth();
int height = sizeSelectorWindow.getHeight();

screenArea = new Rectangle(x,y,width,height);
sizeSelectorWindow.dispatchEvent(new WindowEvent(sizeSelectorWindow, WindowEvent.WINDOW_CLOSING));
}


}

class WindowEventHandler implements WindowListener{

@Override
public void windowOpened(WindowEvent e) {
}

@Override
public void windowClosing(WindowEvent e) {

synchronized (lock) {
sizeSelectorWindow.setVisible(false);
lock.notify();
}
}

@Override
public void windowClosed(WindowEvent e) {
}

@Override
public void windowIconified(WindowEvent e) {
sizeSelectorWindow.setState(JFrame.NORMAL);
Toolkit.getDefaultToolkit().beep();
}

@Override
public void windowDeiconified(WindowEvent e) {}

@Override
public void windowActivated(WindowEvent e) {}

@Override
public void windowDeactivated(WindowEvent e) {}


}

}

测试 1 类:

package screenrecorder;

import java.awt.Rectangle;

public class Test1{

public static void main(String[] args){
System.out.println(new ScreenSizeSelector().getSelectedScreenSize());
}
}

测试2类:

package screenrecorder;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;

public class Test2 extends JFrame{

public Test2(){

JButton btn = new JButton("Click ME");
btn.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
System.out.println(new ScreenSizeSelector().getSelectedScreenSize());

}
});

getContentPane().add(btn);
setSize(100,100);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}

public static void main(String[] args){
new Test2();
}

}

感谢任何帮助。

最佳答案

当您单击按钮时, Action 监听器等待 getSelectedScreenSize() 函数返回。 getSelectedScreenSize() 函数正在等待由 screenSelectorUI() 创建的第二个窗口不可见。 screenSelectorUI() 确实创建了第二个窗口,但您可以像这样设置颜色:

sizeSelectorWindow.setBackground( new Color(0, 0, 0, 0) );

如果您查看颜色构造函数 javadocs:

public Color(int r,
int g,
int b,
int a)

Creates an sRGB color with the specified red, green, blue, and alpha values in the range (0 - 255).
Parameters:

  • r - the red component
  • g - the green component
  • b - the blue component
  • a - the alpha component

您将 alpha 值设置为 0,使其完全不可见。 (alpha 值是透明的)另外,第二个窗口是未修饰的并且不会在关闭时退出,所以您甚至根本不知道它在那里。

我完全不明白 test1 是如何工作的。旁注:当我在 Mac 上尝试测试 1 时,它只显示按钮,我所能做的就是单击它。该按钮将消失,但应用程序仍将运行。

这基本上完全是猜测,但是很多 swing 组件向操作系统发出请求,而不是命令。有点像说,“嘿,我可以调整到 400、400 吗?”操作系统在技术上不必按照您说的去做。我在读How does Java handle multithreading?这表示多线程确实取决于操作系统。我有一种感觉,当 screenSelectorUI() 被自己调用时,它只是在某个地方搞砸了,但当它在某个按钮的线程内时,它以某种方式得到了正确。

关于java - 单击按钮打开时,新 JFrame 以禁用状态打开,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38628709/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com