我的Java应用程序使用两个JFrame - 第一个用于从有限数量的选项(无全屏)向用户提供选项,第二个用于显示数据(使用全屏选项)。
我正在使用 setVisible ()在我的两个帧之间切换,这很好,因为它重用了以前的虚拟桌面并保留了全屏模式,但我不得不切换到 dispose < / strong>()以便隐藏第二个JFrame,原因是toolkit thread paint problem。
当我在第2帧进入全屏模式时,会创建一个新的虚拟桌面 - 但是如果我处理了frame2,那么该VD仍然是一个空的灰色桌面。已经处置()它返回到frame1,如果我再次切换回frame2我们不再全屏...如果我这样做...那么我现在有2个虚拟桌面。等等。
在frame2上使用 setVisible(false)也会留下空的虚拟桌面,虽然这比重绘/缓冲问题少,因为下次我 setVisible(在frame2上至少它在同一个VD中打开,如上所述。
我的问题是:我可以在 dispose()之后使用相同的VD保存和恢复第2帧中的全屏模式,还是我至少可以强制VD关闭?或者我错过了另一个问题的解决方案?或者这只是因为我不严格遵循Apple的全屏指南?!
提前感谢您的帮助。
更新:我回去使用 setVisible (false)来隐藏frame2,但每次显示时都使用 new ()避免重绘/缓冲问题),我再次遇到重复的VD问题。我还实施了 com.apple.eawt.Application.requestToggleFullScreen 以及 com.apple.eawt.FullScreenListener 以在我处置之前退出全屏,但应用程序挂起。现在看起来我将不得不忍受repaint.buffer问题,以允许全屏切换正常工作。
SSCCE:
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class SwingFramesFullScreenMacDemo extends javax.swing.JFrame {
JFrame secondFrame;
JPanel myPanel;
public SwingFramesFullScreenMacDemo() {
//Setup UI With Button to show secondFrame
JPanel thisPanel = new JPanel();
JButton jbtOpenFullScreenFrame = new JButton("Open Full Screen Frame");
jbtOpenFullScreenFrame.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
secondFrame.setVisible(true);
setVisible(false);
}
});
thisPanel.add(jbtOpenFullScreenFrame);
this.add(thisPanel);
this.pack();
// Setup Second Frame With Full Screen Support
secondFrame = new JFrame();
myPanel = new JPanel();
//Dispose() works without residual image, but leaves open virtual desktop for each time
//you go to full screen then dispose
JButton jbtDispose = new JButton("Dispose");
jbtDispose.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setVisible(true);
secondFrame.dispose();
}
});
//SetVisible(false) gives residual image on reopening second frame despite clearing colour
//works well for fullscreen, only one virtual desktop open for lifetime of app
JButton jbtSetVisibleFalse = new JButton("Set Visible to False");
jbtSetVisibleFalse.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
secondFrame.setVisible(false);
setVisible(true);
}
});
myPanel.add(jbtDispose);
myPanel.add(jbtSetVisibleFalse);
secondFrame.add(myPanel);
secondFrame.pack();
enableFullScreenMode(secondFrame);
secondFrame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
setVisible(true);
secondFrame.setVisible(false);
}
});
}
public static void enableFullScreenMode(Window window) {
String methodName = "setWindowCanFullScreen";
try {
Class<?> clazz = Class.forName(com.apple.eawt.FullScreenUtilities.class.getName());
Method method = clazz.getMethod(methodName, new Class<?>[]{
Window.class, boolean.class});
method.invoke(null, window, true);
} catch (ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException t) {
System.err.println("Full screen mode is not supported");
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
javax.swing.JFrame fullScreenMacProblem = new SwingFramesFullScreenMacDemo();
fullScreenMacProblem.addWindowListener(new java.awt.event.WindowAdapter() {
@Override
public void windowClosing(java.awt.event.WindowEvent e) {
System.exit(0);
}
});
fullScreenMacProblem.setVisible(true);
}
});
}
}
答案 0 :(得分:0)
我对这个“catch 22”的解决方案是只在frame1中实例化一次frame2,在frame2不是全屏时使用dispose()(避免重绘/缓冲问题),并在frame2全屏时使用setVisible(false) (为frame2维护一个虚拟桌面)。由于重绘问题不影响全屏视图,因此效果非常好,尽管我确信纯粹主义者会阻挠!