问题
Here my issue, I have 2 Jframe, one for controlling and one for displaying things to publics. I need the display frame to be in fullscreen to avoid publics see things it doesn't need, and I need the controling frame to be usable on the other screen to control the display frame.
Here's my problem, today, I have no problem working this way in Ubuntu and a dual screen mode, but, in Windows 7 buisness 64 (don't try other version yet) The display frame actually goes fullscreen, but when i click anywhere outside the Display frame (control frame include), the display frame is automaticly minimize. I guest it's an issue with windows minimize maximize behaviour, but I really like to make it work. I know a very dirty workaround, that consists in making display frame the size of my screen and position the display frame at the good coordinate.
Here's a sample code of what I do.
To put the Displaying frame in full screen, focus the controling frame and push the key F11. or use the menu (in french)
GameFrame.java equivalent to displaying frame
package ihm;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.plaf.basic.BasicTabbedPaneUI;
public class GameFrame extends javax.swing.JFrame {
public GameFrame() {
initComponents();
}
@SuppressWarnings("unchecked")
private void initComponents() {
mainPanel = new javax.swing.JTabbedPane();
gamePanel = new javax.swing.JPanel(){
public void paintComponent(Graphics g){
super.paintComponent(g);
if(backgroundImage != null){
g.drawImage(backgroundImage, 0, 0, this.getWidth(),this.getHeight(),null);
}
}
};
votePanel = new javax.swing.JPanel();
countdownPanel = new javax.swing.JPanel();
bienvenuePanel = new javax.swing.JPanel();
adsPanel = new javax.swing.JPanel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("ImproAffichage");
setAlwaysOnTop(true);
setBackground(new java.awt.Color(255, 179, 0));
setForeground(java.awt.Color.white);
setUndecorated(true);
getContentPane().setLayout(new java.awt.GridLayout(1, 1));
mainPanel.setTabLayoutPolicy(javax.swing.JTabbedPane.SCROLL_TAB_LAYOUT);
gamePanel.setBackground(new java.awt.Color(255, 168, 0));
gamePanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(40, 40, 40, 40));
gamePanel.setMinimumSize(new java.awt.Dimension(200, 200));
gamePanel.setLayout(new java.awt.GridLayout(2, 2, 70, 70));
mainPanel.addTab("score", gamePanel);
votePanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10));
votePanel.setLayout(new java.awt.GridLayout(1, 0));
mainPanel.addTab("vote", votePanel);
countdownPanel.setLayout(new java.awt.GridLayout(1, 0));
mainPanel.addTab("decompte", countdownPanel);
bienvenuePanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10));
bienvenuePanel.setLayout(new java.awt.GridLayout(1, 0));
mainPanel.addTab("Bienvenue", bienvenuePanel);
adsPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10));
adsPanel.setLayout(new java.awt.GridLayout(1, 0));
mainPanel.addTab("publicité", adsPanel);
getContentPane().add(mainPanel);
mainPanel.setUI(new BasicTabbedPaneUI() {
protected int calculateTabAreaHeight(int tab_placement, int run_count, int max_tab_height) {
return 0;
}
});
pack();
}
public static void main(String args[]) {
/*
* If Nimbus (introduced in Java SE 6) is not available, stay with the
* default look and feel. For details see
* http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(GameFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(GameFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(GameFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(GameFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
/*
* Create and display the form
*/
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new GameFrame().setVisible(true);
}
});
}
private static GameFrame instance;
private Image backgroundImage;
private Image decompteImage;
private Image bienvenueImage;
// Variables declaration - do not modify
private javax.swing.JPanel adsPanel;
private javax.swing.JPanel bienvenuePanel;
private javax.swing.JPanel countdownPanel;
private javax.swing.JPanel gamePanel;
private javax.swing.JTabbedPane mainPanel;
private javax.swing.JPanel votePanel;
// End of variables declaration
public static GameFrame getInstance() {
if (instance == null) {
instance = new GameFrame();
}
return instance;
}
public void refresh() {
this.validate();
this.repaint();
this.pack();
}
}
ControlFrame.java
equivalent to controling frame
package ihm;
import java.awt.Dimension;
import java.awt.GraphicsDevice;
public class ControlFrame extends javax.swing.JFrame {
public static ControlFrame getInstance() {
if (instance == null) {
instance = new ControlFrame();
}
return instance;
}
private ControlFrame() {
this.gameFrame = GameFrame.getInstance();
this.gameFrame.setBounds(100, 100, 400, 300);
this.gameFrame.pack();
this.gameFrame.setVisible(true);
initComponents();
}
@SuppressWarnings("unchecked")
private void initComponents() {
transitionPanel = new javax.swing.JPanel();
jbBienvenue = new javax.swing.JButton();
jbScore = new javax.swing.JButton();
jbVote = new javax.swing.JButton();
jbDecompte = new javax.swing.JButton();
jbPublicite = new javax.swing.JButton();
jpPlayerControl = new javax.swing.JPanel();
jMenuBar1 = new javax.swing.JMenuBar();
mainMenu = new javax.swing.JMenu();
jmScore = new javax.swing.JMenu();
jmiAddTeam = new javax.swing.JMenuItem();
jmiFullscreen = new javax.swing.JMenuItem();
jmiBackground = new javax.swing.JMenuItem();
jMenuItem1 = new javax.swing.JMenuItem();
jmiPointPath = new javax.swing.JMenuItem();
jmOtherImage = new javax.swing.JMenu();
jmiVote = new javax.swing.JMenuItem();
jmiDecompte = new javax.swing.JMenuItem();
jmiBienvenue = new javax.swing.JMenuItem();
jmiAds = new javax.swing.JMenuItem();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("ImproContro");
setAlwaysOnTop(true);
setBounds(new java.awt.Rectangle(0, 0, 200, 300));
setForeground(java.awt.Color.white);
setPreferredSize(new java.awt.Dimension(400, 500));
setResizable(false);
getContentPane().setLayout(new java.awt.BorderLayout(25, 25));
transitionPanel.setLayout(new java.awt.GridLayout(1, 6));
jbBienvenue.setText("Bienvenue");
transitionPanel.add(jbBienvenue);
jbScore.setText("Score");
transitionPanel.add(jbScore);
jbVote.setText("Aux votes");
transitionPanel.add(jbVote);
jbDecompte.setText("Decompte");
transitionPanel.add(jbDecompte);
jbPublicite.setText("Publicité");
transitionPanel.add(jbPublicite);
getContentPane().add(transitionPanel, java.awt.BorderLayout.PAGE_START);
jpPlayerControl.setBackground(new java.awt.Color(255, 220, 0));
jpPlayerControl.setLayout(new java.awt.GridLayout(2, 2, 10, 10));
getContentPane().add(jpPlayerControl, java.awt.BorderLayout.CENTER);
mainMenu.setText("File");
jMenuBar1.add(mainMenu);
jmScore.setText("Score");
jmiAddTeam.setText("ajouter equipe");
jmScore.add(jmiAddTeam);
jmiFullscreen.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F11, 0));
jmiFullscreen.setText("Plein Ecran");
jmScore.add(jmiFullscreen);
jmiBackground.setText("image \"fond score\"");
jmScore.add(jmiBackground);
jMenuItem1.setText("couleur \"fond score\"");
jmScore.add(jMenuItem1);
jmiPointPath.setText("Icone de point");
jmScore.add(jmiPointPath);
jMenuBar1.add(jmScore);
jmOtherImage.setText("Autre images");
jmiVote.setText("image \"aux votes\"");
jmOtherImage.add(jmiVote);
jmiDecompte.setText("image \"fond Decompte\"");
jmOtherImage.add(jmiDecompte);
jmiBienvenue.setText("image \"Bienvenue\"");
jmOtherImage.add(jmiBienvenue);
jmiAds.setText("Ajouter image annonce");
jmOtherImage.add(jmiAds);
jMenuBar1.add(jmOtherImage);
setJMenuBar(jMenuBar1);
jmiFullscreen.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F11, 0));
jmiFullscreen.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jmiFullscreenActionPerformed(evt);
}
});
pack();
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(ControlFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(ControlFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(ControlFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(ControlFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
/*
* * Create and display the form
*/ java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
ControlFrame.getInstance().setVisible(true);
}
});
}
private void jmiFullscreenActionPerformed(java.awt.event.ActionEvent evt) {
GraphicsDevice gd = this.gameFrame.getGraphicsConfiguration().getDevice();
if (gd.getFullScreenWindow() != null) {
gd.setFullScreenWindow(null);
this.gameFrame.setResizable(true);
this.gameFrame.setPreferredSize(new Dimension(400, 300));
} else {
this.gameFrame.setResizable(false);
this.gameFrame.setPreferredSize(new Dimension(gd.getDefaultConfiguration().getBounds().getSize()));
this.gameFrame.enableInputMethods(false);
gd.setFullScreenWindow(this.gameFrame);
}
refresh();
}
private static ControlFrame instance;
private GameFrame gameFrame;
// Variables declaration - do not modify
private javax.swing.JMenuBar jMenuBar1;
private javax.swing.JMenuItem jMenuItem1;
private javax.swing.JButton jbBienvenue;
private javax.swing.JButton jbDecompte;
private javax.swing.JButton jbPublicite;
private javax.swing.JButton jbScore;
private javax.swing.JButton jbVote;
private javax.swing.JMenu jmOtherImage;
private javax.swing.JMenu jmScore;
private javax.swing.JMenuItem jmiAddTeam;
private javax.swing.JMenuItem jmiAds;
private javax.swing.JMenuItem jmiBackground;
private javax.swing.JMenuItem jmiBienvenue;
private javax.swing.JMenuItem jmiDecompte;
private javax.swing.JMenuItem jmiFullscreen;
private javax.swing.JMenuItem jmiPointPath;
private javax.swing.JMenuItem jmiVote;
private javax.swing.JPanel jpPlayerControl;
private javax.swing.JMenu mainMenu;
private javax.swing.JPanel transitionPanel;
// End of variables declaration
public void refresh() {
System.out.println("refresh()");
this.gameFrame.refresh();
this.validate();
this.repaint();
}
}
Edit1:
I try to fullscreen both windows, but when a filechooser is called, the focus is lost because of the always on top behaviour of a fullscreen windows.
Edit 2:
I also tried to put a listener on iconified displaying jframe, but if I try to change state to NORMAL, the displaying jframe request focus, and my second frame can't be used because it lost focus
Edit 3:
If the display frame is not fullscreened, then it's not minimized when clicking on the controlling frame.
回答1:
So here my own anwser to my own problem, the workaround I finally use and I think is the only not so ugly workaround I can found is to use this code
private void jmiFullscreenActionPerformed(java.awt.event.ActionEvent evt) {
GraphicsDevice gd = this.gameFrame.getGraphicsConfiguration().getDevice();
if (!this.gameFrame.isResizable() ) {
//gd.setFullScreenWindow(null);
this.gameFrame.setResizable(true);
this.gameFrame.setPreferredSize(new Dimension(400, 300));
} else {
this.gameFrame.setResizable(false);
this.gameFrame.setPreferredSize(new Dimension(gd.getDefaultConfiguration().getBounds().getSize()));
this.gameFrame.setExtendedState(Frame.MAXIMIZED_BOTH);
}
refresh();
}
instead of this in my original example
private void jmiFullscreenActionPerformed(java.awt.event.ActionEvent evt) {
GraphicsDevice gd = this.gameFrame.getGraphicsConfiguration().getDevice();
if (gd.getFullScreenWindow() != null) {
gd.setFullScreenWindow(null);
this.gameFrame.setResizable(true);
this.gameFrame.setPreferredSize(new Dimension(400, 300));
} else {
this.gameFrame.setResizable(false);
this.gameFrame.setPreferredSize(new Dimension(gd.getDefaultConfiguration().getBounds().getSize()));
this.gameFrame.enableInputMethods(false);
gd.setFullScreenWindow(this.gameFrame);
}
refresh();
}
So finally I'm not using the java fullscreen function and I just use some properties of my jframe to make it look like a fullscreen frame.
Hope it help some of you !! have a nice day
回答2:
this might help you
I prefer the custom way u used :) and I came up with this solution when I face the same problem but the issue is with the Java's Fullscreen API.
来源:https://stackoverflow.com/questions/9179297/java-fullscreen-jframe-with-dual-monitor