Basically I need to do this for school, Ive been through all kinds of posts about this and everyone just says "why'd you wanna do that?" and don't answer. So a lot of people need help on this and your answer could get a lot of likes someday
So here's my class - what couple lines of code do i need to add to main to make this JApplet pop up and draw the bricks into a JApplet window?
public class Wall extends JApplet {
ArrayList<Brick> bricks = new ArrayList<Brick>();
Color[] colors = {Color.decode("#1abc9c"), Color.decode("#f1c40f"), Color.decode("#d35400"), Color.decode("#e74c3c"), Color.decode("#2ecc71"), Color.decode("#3498db"), Color.decode("#9b59b6"), Color.decode("#34495e")};
ArrayList<Integer> usedInts = new ArrayList<Integer>();
public void makeBricks(){
int xPos = 20;
int yPos = 50;
int height = 50;
int width = 60;
for(int i=0; i<8;i++){
Brick b = new Brick();
b.setxPosition(xPos);
xPos =+60;
b.setyPosition(yPos);
if (xPos == 200){
yPos+=50;
}
b.setColor(randomColor());
b.setHeight(height);
b.setWidth(width);
bricks.add(b);
}
}
public Color randomColor(){
Random r = new Random(System.currentTimeMillis());
boolean allAssigned = false;
while(!allAssigned){
int newInt = r.nextInt(8);
if(!usedInts.contains(newInt)){
usedInts.add(newInt);
return colors[newInt];
}
if(usedInts.size()>7){
usedInts.clear();
}
}
return Color.BLACK;
}
public void draw(Graphics g) {
for(Brick b: bricks){
b.draw(g);
}
}
#Override
public void paint(Graphics g){
draw(g);
}
public static void main(String[] args) {
//these lines do not work
Wall wall = new Wall();
wall.makeBricks();
wall.draw();
}
}
JApplet's don't have a window of their own, they are embedded within a web page by a browser. It's possible to use the applet viewer to display them, but you'd need to do that from the command line
Start by creating a custom class the extends from something like JPanel, override it's paintComponent and perform you custom painting there. See Performing Custom Painting for more details.
In your main method, create a new JFrame and add your "game panel" to it...
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new GamePane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
If you MUST have a applet, you can now add the "game panel" to it as well
See How to Make Frames (Main Windows) and Using Top-Level Containers for more details
As mentioned by others, applets don't normally have a standalone window. On the other hand, there are at least 3 ways in which an applet can be included in a free floating window:
Run the applet in applet viewer1.1. This should be seriously considered, since the applet viewer is designed to display applets. Better still, it will recreate most of the environment of an applet in a web page, including creating an applet context (from which to get the document or code base, or applet parameters) and a security sand-box.
If you mean 'free floating for the end user'. Launch the applet free floating using Java Web Start. JWS uses the applet viewer (again) to show the applet.
A hybrid application/applet1.2. This is more like you described, an applet with a main(String[]) that creates a wrapper frame for the applet and calls the init() method etc. This is handy for testing simpler (no parameters etc.) applets where the security sand-box just gets in the way.
I also had a site where I provided Appleteer, similar to applet viewer except it would launch multiple applets in a single HTML document, whereas the applet viewer would split them into separate free floating windows (and other slight differences - Appleteer had no security sandbox..). Unfortunately my free hosting for the sites stopped running the web hosting side of the business!
This answer to How to call a paint method inside Applet extended class?
Update 1 has an example of launching an applet in the applet viewer.
Update 2 has an example of creating a hybrid application/applet.
Related
I have been designing a Swing-based tabletop RPG program to facilitate text-based roleplay with GUI control elements.
To facilitate this, each running client gets a main desktop ("GM Desktop" on the hosting client and "Player Desktop" on the remote clients) with all of the important JFrames. Additionally, both GM and Players can open "Perspective Desktops" for characters, providing them with a separate JDesktopPane that contains the "Role Play Chat Window" that gives that character's perspective, along with additional JInternalFrames such as the "Character Sheet Window", etc.
The user navigates between desktops using a JTabbedPane.
The issue that I am having is that SOME of the windows I want to be able to move between desktops. For example, if the OOC (Out-of-Character) Chat receives a message while the user is in a Perspective Desktop, I want there to be an option for the OOC Chat Window to automatically relocate to the current desktop so the user sees the message immediately. Similarly I want the player to be able to "call" certain windows into the current desktop using the menu bar.
However, when I attempt to move a JInternalFrame from one JDesktopPane to another, I receive an exception.
com.finnickslab.textroleplayonline.exceptions.CommandEventHandlingException
An exception was thrown during command handling. CommandEvent type: UI_OOC_CHAT (26).
Cause Exception: java.lang.IllegalArgumentException
illegal component position
java.awt.Container.addImpl(Unknown Source)
javax.swing.JLayeredPane.addImpl(Unknown Source)
javax.swing.JDesktopPane.addImpl(Unknown Source)
java.awt.Container.add(Unknown Source)
com.finnickslab.textroleplayonline.ui.GameDesktop.receiveTransfer(GameDesktop.java:80)
com.finnickslab.textroleplayonline.ui.GameDesktop.access$0(GameDesktop.java:74)
com.finnickslab.textroleplayonline.ui.GameDesktop$2.run(GameDesktop.java:69)
com.finnickslab.textroleplayonline.ui.UI.invokeEvent(UI.java:818)
com.finnickslab.textroleplayonline.ui.GameDesktop.transfer(GameDesktop.java:62)
com.finnickslab.textroleplayonline.ui.UI$HostCommandHandler.handle(UI.java:605)
com.finnickslab.textroleplayonline.comm.Server$3.run(Server.java:324)
All JInternalFrames in my program descend from the same subclass of JInternalFrame ("InternalWindow").
The exception makes it look a little convoluted but it boils down to calling JDesktopPane.remove(JInternalFrame) then JDesktopPane.add(JInternalFrame).
And then I receive that exception as soon as the "add" method is called on GameDesktop line 80.
/**
* Transfers the specified InternalWindow from this GameDesktop to
* the specified GameDesktop. Use this method to prevent
* automatic removal of listeners performed with the
* {#link GameDesktop.remove(InternalWindow)} method.
*/
public synchronized void transfer(
final InternalWindow window,
final GameDesktop gd) {
final GameDesktop desktop = this;
contents.remove(window);
UI.invokeEvent(new Runnable() {
#Override
public void run() {
desktop.remove((JInternalFrame) window);
desktop.validate();
desktop.repaint();
gd.receiveTransfer(window);
}
});
}
private synchronized void receiveTransfer(InternalWindow window) {
contents.add(window);
window.changeDesktop(this);
window.center();
this.add((JInternalFrame) window); // LINE 80
this.validate();
this.repaint();
window.resetPosition();
}
The "UI.invokeEvent(Runnable)" method is a convenience method I wrote for SwingUtilities.invokeAndWait(Runnable). It checks to see if the current thread is the EDT and, if it is, executes the run() method immediately. Otherwise, it uses invokeAndWait(Runnable) to schedule the runnable on the EDT.
Any ideas of how to fix this problem would be appreciated.
EDIT:
All my research on this error suggests that it has something to do with the Z-axis position of the component. I tried changing the add call to specify the z position
super.add(window, getComponentCount());
but no change. Still getting the same IllegalArgumentException.
See if you get the same error when running this. If not, the problem is not with switching the parent of the internal frame, it's with the synchronization.
public class IFSwitch extends JDesktopPane {
final JDesktopPane pane1 = this;
public IFSwitch() {
JFrame frame1 = new JFrame("Frame1");
JFrame frame2 = new JFrame("Frame2");
// JDesktopPane pane1 = new JDesktopPane();
JDesktopPane pane2 = new JDesktopPane();
final JInternalFrame if1 = new JInternalFrame();
frame1.add(pane1);
frame2.add(pane2);
pane1.add(if1);
if1.setBounds(10, 10, 100, 100);
frame1.setBounds(100, 100, 200, 200);
frame2.setBounds(500, 500, 200, 200);
frame1.setVisible(true);
frame2.setVisible(true);
if1.setVisible(true);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
pane2.add(if1);
pane1.remove(if1); // You don't even need this line.
pane1.repaint();
}
public static void main(String[] args) {
new IFSwitch();
}
}
Update 12/21:
7u10 was recently released. Confirmed that:
The issue still persists
Thankfully, the workaround still functions!
Update 11/7:
And we have a workaround!
Leonid Romanov from Oracle on the openjdk.java.net mailing list provided some insight as to what's going on:
Well, although I'm not 100% sure yet, but it looks like when we enter full screen some other window becomes the first responder, hence the beep. Could you please try the following workaround: after calling setFullScreenWindow() on a frame, call setVisible(false) followed by setVisible(true). This, in theory, should restore the correct first responder.
The snippet of code that seems to work is simply:
dev.setFullScreenWindow(f);
f.setVisible(false);
f.setVisible(true);
I have updated the sample code with the ability to toggle this fix on and off; it is required every time a window enters fullscreen.
In the larger context of my more complex application, I am still running into keyboard focus issues on subcomponents within the fullscreen window, where a mouse click causes my window to lose focus. (I'm guessing it's going to the undesired first responder window referenced above.) I'll report back when I have more information about this case - I cannot reproduce it in the smaller sample yet.
Update 10/31:
Major update to the sample code:
Includes toggle between FullScreen exclusive and Lion-style FullScreen modes
Listens to the KeyboardFocusManager to display the hierarchy for the currently focused component
Uses both input maps and KeyListeners to try to capture input
Also did some more digging with coworkers to try to isolate issues:
On one front, we tried overriding some methods in RT.jar to see if there were problems with the way the screen device is being selected. Also tried were the entry points to the Toolkit.beep() functionality to see if the alert sounds were coming from the Java side - appears not.
On another front, it was clear that not even the native side is receiving keyboard events. A coworker attributes this to a switch from an AWTView to a NSWindow in 7u6.
A selection of existing Oracle bugs has been found, which you can look up here:
8000276 : [macosx] graphicsDevice.setFullScreenWindow(frame) crashes JVM
8000430 : [macosx] java.awt.FileDialog issues on macosx
7175707 : [macosx] PIT: 8 b43 Not running on AppKit thread issue again
Update 10/26:
Thanks to the comment by #maslovalex below regarding an Applet working on 7u5, I went back and painstakingly examined compatibility with the JDK versions for OSX:
10.7.1 with 7u4: Fullscreen Works!
10.7.1 with 7u5: Fullscreen Works!
10.7.5 with 7u5: Fullscreen Works!
10.7.5 with 7u6: Fullscreen Breaks :(
Combined with the other tests noted elsewhere, it's clear there was an issue introduced with 7u6 that remains in 7u7 and 7u9, and it affects both Lion 10.7 and Mountain Lion 10.8.
7u6 was a major milestone release, bringing full support of the JRE and JDK to Mac OS X and also including Java FX as part of the distribution. Further info is available in the Release Notes and the Roadmap. It's not tremendously surprising that such an issue could crop up as support shifts to Java FX.
The question becomes:
Will Oracle fix this in a near-term release of the JDK? (If you have links to existing bugs, please include them here.)
Is a workaround possible in the interim?
Other updates from today:
I incorporated the Apple extensions approach to fullscreen mode as an alternate path of exploration (updated sample code pending cleanup). The good news: input works! The bad news: there really don't seem to be any kiosking/isolation options.
I tried killing the Dock - directly or with an App - as I understand the Dock is responsible for Command-Tab app switching, Mission Control, and Launch Pad, only to find out that it's responsible for the handling of fullscreen apps as well! As such, the Java calls become non-functional and never return.
If there's a way to disable Command-Tab (and Mission Control and Launchpad and Spaces) without affecting the Dock's fullscreen handling, that would be extremely useful. Alternatively, one can try to remap certain keys such as Command, but that will affect the ability to use that modifier elsewhere in the program and the system itself (not exactly ideal, when you need to Command-C to copy some text).
I've had no luck with KeyListeners (I'm not receiving any callbacks), but I have a few more options to try.
Based on a coworker's suggestion, I tried ((sun.lwawt.macosx.LWCToolkit)Toolkit.getDefaultToolkit()).isApplicationActive() via reflection. The idea was that it:
is a native method with the comment "Returns true if the application (one of its windows) owns keyboard focus.". Calls to this method were added in CPlatformWindow.java in the past few months related to focus logic. If it returns false in your test code, it's probably part of the problem.
Unfortunately, everywhere I checked it, the method returned true. So even according to the low level system, my windows should have keyboard focus.
My previous optimism regarding the JAlbum fix has been dashed. The developer posted a response on their forum that explains how they simply removed proper fullscreen support on OS X while running Java 7. They have a bug into Oracle (and I'm hoping to get the bug number).
Update 10/25:
I have now also tried Java 7u9 on Lion 10.7.4 and have seen the exact same issue, so it's JDK- not OS-specific.
The core question has become whether you can embed in a fullscreen window core Swing Components that have default handling for keyboard input (JTextField/JTextArea or even editable combo boxes) and expect them to behave normally (without having to resort to rebuilding their basic key bindings manually). Also in question is whether other stalwarts of windowed layouts, such as using tab for focus traversal, should work.
The ideal goal would be to have the ability take a windowed Swing app with all of its buttons, tabs, fields, etc. and run it in fullscreen exclusive/kiosk mode with most functionality intact. (Previously, I have seen that Dialog pop ups or ComboBox drop downs do not function in fullscreen on Java 6 on OS X, but other Components behave fine.)
I'll be looking into the eawt FullScreen capabilities, which will be interesting if they support kiosk lock down options, such as eliminating Command-Tab application switching.
Original Question:
I have a Swing app that for years has supported FullScreen (exclusive) mode on Mac OS X up through Java 6. I've been doing compatibility testing with the latest Mountain Lion release (10.8.2 Supplemental) and Oracle's JDK 7 and noticed a glaring issue while in that mode: mouse movement and clicks work fine, but keyboard input is not delivered to the components.
(I've narrowed this down in a test case below to not being able to type into a simple JTextField while in fullscreen mode.)
One symptom is that each key press results in a system beep, as if the OS is disallowing keyboard events from being delivered to the application.
Separately, my application has an exit hook installed, and the Command-Q combo will trigger that hook - it's clear that the OS is listening to standard key combos.
I have tested this separately on three different Macs with various installs:
On Apple Java 6u35 and 6u37: both windowed and fullscreen modes receive input.
On Oracle Java 7u7 and 7u9: windowed mode works as expected while fullscreen has the symptoms above.
This may have been previously reported:
Java Graphics Full Screen Mode not Registering Keyboard Input.
However, that question is not specific about the Java version or platform.
Additional searching has turned up a separate fullscreen option introduced in Lion:
Fullscreen feature for Java Apps on OSX Lion.
I have yet to try using this approach, as keyboard input seems integral to the target use cases of FullScreen Exclusive mode, such as games.
There is some mention in the JavaDoc for this mode that input methods might be disabled. I tried to call the suggested Component.enableInputMethods(false), but it seemed to have no effect.
I'm somewhat optimistic that there's a solution to this issue based on an entry in the release notes of a Java app I came across (JAlbum). A stated fix for 10.10.6: "Keyboard support wasn't working when running the full screen slide show on Mac and Java 7"
My test case is below. It is lightly modified from the second example in this issue (which, unmodified, also exhibits my problem): How to handle events from keyboard and mouse in full screen exclusive mode in java?
In particular, it adds a button to toggle fullscreen.
import java.lang.reflect.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.beans.*;
/** #see https://stackoverflow.com/questions/13064607/ */
public class FullScreenTest extends JPanel {
private GraphicsDevice dev = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
private JFrame f = new JFrame("FullScreenTest");
private static final String EXIT = "Exit";
private Action exit = new AbstractAction(EXIT) {
#Override
public void actionPerformed(ActionEvent e) {
Object o = dev.getFullScreenWindow();
if(o != null) {
dev.setFullScreenWindow(null);
}
f.dispatchEvent(new WindowEvent(f, WindowEvent.WINDOW_CLOSING));
}
};
private JButton exitBTN = new JButton(exit);
private JTextField jtf = new JTextField("Uneditable in FullScreen with Java7u6+ on Mac OS X 10.7.3+");
private JLabel keystrokeLabel = new JLabel("(Last Modifier+Key Pressed in JTextField)");
private JLabel jtfFocusLabel = new JLabel("(JTextField Focus State)");
private JLabel focusLabel = new JLabel("(Focused Component Hierarchy)");
private JCheckBox useOSXFullScreenCB = new JCheckBox("Use Lion-Style FullScreen Mode");
private JCheckBox useWorkaroundCB = new JCheckBox("Use Visibility Workaround to Restore 1st Responder Window");
private static final String TOGGLE = "Toggle FullScreen (Command-T or Enter)";
private Action toggle = new AbstractAction(TOGGLE) {
#Override
public void actionPerformed(ActionEvent e) {
Object o = dev.getFullScreenWindow();
if(o == null) {
f.pack();
/**
* !! Neither of these calls seem to have any later effect.
* One exception: I have a report of a
* Mini going into an unrecoverable black screen without setVisible(true);
* May be only a Java 6 compatibility issue. !!
*/
//f.setVisible(true);
//f.setVisible(false);
if(!useOSXFullScreenCB.isSelected()) {
// No keyboard input after this call unless workaround is used
dev.setFullScreenWindow(f);
/**
* Workaround provided by Leonid Romanov at Oracle.
*/
if(useWorkaroundCB.isSelected()) {
f.setVisible(false);
f.setVisible(true);
//Not necessary to invoke later...
/*SwingUtilities.invokeLater(new Runnable() {
public void run() {
f.setVisible(false);
f.setVisible(true);
}
});*/
}
}
else {
toggleOSXFullscreen(f);
}
}
else {
dev.setFullScreenWindow(null);
f.pack();
f.setVisible(true);
}
isAppActive();
}
};
private JButton toggleBTN = new JButton(toggle);
public FullScreenTest() {
// -- Layout --
this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
exitBTN.setAlignmentX(JComponent.CENTER_ALIGNMENT);
exitBTN.setMaximumSize(new Dimension(Short.MAX_VALUE, 50));
this.add(exitBTN);
jtf.setAlignmentX(JComponent.CENTER_ALIGNMENT);
jtf.setMaximumSize(new Dimension(Short.MAX_VALUE, Short.MAX_VALUE));
this.add(jtf);
keystrokeLabel.setAlignmentX(JComponent.CENTER_ALIGNMENT);
keystrokeLabel.setMaximumSize(new Dimension(Short.MAX_VALUE, 50));
keystrokeLabel.setHorizontalAlignment(SwingConstants.CENTER);
keystrokeLabel.setForeground(Color.DARK_GRAY);
this.add(keystrokeLabel);
jtfFocusLabel.setAlignmentX(JComponent.CENTER_ALIGNMENT);
jtfFocusLabel.setMaximumSize(new Dimension(Short.MAX_VALUE, 50));
jtfFocusLabel.setHorizontalAlignment(SwingConstants.CENTER);
jtfFocusLabel.setForeground(Color.DARK_GRAY);
this.add(jtfFocusLabel);
focusLabel.setAlignmentX(JComponent.CENTER_ALIGNMENT);
focusLabel.setMaximumSize(new Dimension(Short.MAX_VALUE, 50));
focusLabel.setHorizontalAlignment(SwingConstants.CENTER);
focusLabel.setForeground(Color.DARK_GRAY);
this.add(focusLabel);
useOSXFullScreenCB.setAlignmentX(JComponent.CENTER_ALIGNMENT);
useOSXFullScreenCB.setMaximumSize(new Dimension(Short.MAX_VALUE, 50));
useOSXFullScreenCB.setHorizontalAlignment(SwingConstants.CENTER);
this.add(useOSXFullScreenCB);
useWorkaroundCB.setAlignmentX(JComponent.CENTER_ALIGNMENT);
useWorkaroundCB.setMaximumSize(new Dimension(Short.MAX_VALUE, 50));
useWorkaroundCB.setHorizontalAlignment(SwingConstants.CENTER);
this.add(useWorkaroundCB);
toggleBTN.setAlignmentX(JComponent.CENTER_ALIGNMENT);
toggleBTN.setMaximumSize(new Dimension(Short.MAX_VALUE, 50));
this.add(toggleBTN);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setResizable(false);
f.setUndecorated(true);
f.add(this);
f.pack();
enableOSXFullscreen(f);
// -- Listeners --
// Default BTN set to see how input maps respond in fullscreen
f.getRootPane().setDefaultButton(toggleBTN);
// Explicit input map test with Command-T toggle action from anywhere in the window
this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
KeyStroke.getKeyStroke(KeyEvent.VK_T, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()),
toggle.getValue(Action.NAME));
this.getActionMap().put(toggle.getValue(Action.NAME), toggle);
// KeyListener test
jtf.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
String ktext = "KeyPressed: "+e.getKeyModifiersText(e.getModifiers()) + "_"+ e.getKeyText(e.getKeyCode());
keystrokeLabel.setText(ktext);
System.out.println(ktext);
}
});
// FocusListener test
jtf.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent fe) {
focused(fe);
}
public void focusLost(FocusEvent fe) {
focused(fe);
}
private void focused(FocusEvent fe) {
boolean allGood = jtf.hasFocus() && jtf.isEditable() && jtf.isEnabled();
jtfFocusLabel.setText("JTextField has focus (and is enabled/editable): " + allGood);
isAppActive();
}
});
// Keyboard Focus Manager
KeyboardFocusManager focusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
focusManager.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent e) {
if (!("focusOwner".equals(e.getPropertyName()))) return;
Component comp = (Component)e.getNewValue();
if(comp == null) {
focusLabel.setText("(No Component Focused)");
return;
}
String label = comp.getClass().getName();
while(true) {
comp = comp.getParent();
if(comp == null) break;
label = comp.getClass().getSimpleName() + " -> " + label;
}
focusLabel.setText("Focus Hierarchy: " + label);
isAppActive();
}
});
}
/**
* Hint that this Window can enter fullscreen. Only need to call this once per Window.
* #param window
*/
#SuppressWarnings({"unchecked", "rawtypes"})
public static void enableOSXFullscreen(Window window) {
try {
Class util = Class.forName("com.apple.eawt.FullScreenUtilities");
Class params[] = new Class[]{Window.class, Boolean.TYPE};
Method method = util.getMethod("setWindowCanFullScreen", params);
method.invoke(util, window, true);
} catch (ClassNotFoundException e1) {
} catch (Exception e) {
System.out.println("Failed to enable Mac Fullscreen: "+e);
}
}
/**
* Toggle OSX fullscreen Window state. Must call enableOSXFullscreen first.
* Reflection version of: com.apple.eawt.Application.getApplication().requestToggleFullScreen(f);
* #param window
*/
#SuppressWarnings({"unchecked", "rawtypes"})
public static void toggleOSXFullscreen(Window window) {
try {
Class appClass = Class.forName("com.apple.eawt.Application");
Method method = appClass.getMethod("getApplication");
Object appInstance = method.invoke(appClass);
Class params[] = new Class[]{Window.class};
method = appClass.getMethod("requestToggleFullScreen", params);
method.invoke(appInstance, window);
} catch (ClassNotFoundException e1) {
} catch (Exception e) {
System.out.println("Failed to toggle Mac Fullscreen: "+e);
}
}
/**
* Quick check of the low-level window focus state based on Apple's Javadoc:
* "Returns true if the application (one of its windows) owns keyboard focus."
*/
#SuppressWarnings({"unchecked", "rawtypes"})
public static void isAppActive() {
try {
Class util = Class.forName("sun.lwawt.macosx.LWCToolkit");
Method method = util.getMethod("isApplicationActive");
Object obj = method.invoke(Toolkit.getDefaultToolkit());
System.out.println("AppActive: "+obj);
} catch (ClassNotFoundException e1) {
} catch (Exception e) {
System.out.println("Failed to check App: "+e);
}
}
public static void main(String[] args) {
System.out.println("Java Version: " + System.getProperty("java.version"));
System.out.println("OS Version: " + System.getProperty("os.version"));
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
FullScreenTest fst = new FullScreenTest();
if(!fst.dev.isFullScreenSupported()) {
System.out.println("FullScreen not supported on this graphics device. Exiting.");
System.exit(0);
}
fst.toggle.actionPerformed(null);
}
});
}
}
This is because the component to which you added the other has now lost focus, you can fix this by either:
calling requestFocus() on the component instance to which you add KeyBindings
or
alternatively use JComponent.WHEN_IN_FOCUSED_WINDOW with KeyBindings:
component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_Q, 0),
"doSomething");
component.getActionMap().put("doSomething",
anAction);
Reference:
How to Use Key Bindings
Instead, use key bindings, as shown in this FullScreenTest. Also, consider a DocumentListener, shown here, for text components.
I think I finally found a solution, registering click listeners against to the JFrame itself. (This is a class which extends JFrame, hence all the "this" references.)
/**
* Toggles full screen mode. Requires a lot of references to the JFrame.
*/
public void setFullScreen(boolean fullScreen){
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice dev = env.getDefaultScreenDevice();//Gets the main screen
if(!fullScreen){//Checks if a full screen application isn't open
this.dispose();//Restarts the JFrame
this.setVisible(false);
this.setResizable(true);//Re-enables resize-ability.
this.setUndecorated(false);//Adds title bar back
this.setVisible(true);//Shows restarted JFrame
this.removeMouseListener(macWorkAround);
this.pack();
this.setExtendedState(this.getExtendedState()|JFrame.MAXIMIZED_BOTH);//Returns to maximized state
this.fullScreen = false;
}
else{
this.dispose();//Restarts the JFrame
this.setResizable(false);//Disables resizing else causes bugs
this.setUndecorated(true);//removes title bar
this.setVisible(true);//Makes it visible again
this.revalidate();
this.setSize(Toolkit.getDefaultToolkit().getScreenSize());
try{
dev.setFullScreenWindow(this);//Makes it full screen
if(System.getProperty("os.name").indexOf("Mac OS X") >= 0){
this.setVisible(false);
this.setVisible(true);
this.addMouseListener(macWorkAround);
}
this.repaint();
this.revalidate();
}
catch(Exception e){
dev.setFullScreenWindow(null);//Fall back behavior
}
this.requestFocus();
this.fullScreen = true;
}
}
private MouseAdapter macWorkAround = new MouseAdapter(){
public void mouseClicked(MouseEvent e){
MainGUI.this.setVisible(false);
MainGUI.this.setVisible(true);
}
};
I am having trouble with ImageIcon().GetImage()
The strange thing is, is that it sometimes works and shows me the window with the maps on it, and other times it doesn't. It also works on other computers flawlessly but not on mine!
I have tried everything, reinstalling Java, reinstalling IntelliJ, also disabling my firewall, but to no avail. I have also written a similar program in C# which works perfectly, which leads me to believe it isn't a permissions error. I have also tested it on a basic Windows XP system with an on board graphics card which also works perfectly.
Here is my code:
public class main {
public static void main(String[] args) {
System.out.println("Running main..");
try
{
URL url = new URL("http://maps.googleapis.com/maps/api/staticmap?center=-33.80382155278416,18.567184266922002&zoom=17&size=1024x1024&maptype=hybrid&sensor=false&format=png&key=AIzaSyCVnp9iTXRSS3ZE5FjzF7uNZavazWhLko4");
Image img=new ImageIcon(url).getImage();
System.out.println("INFO :"+img);
new ImageFrame(img);
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static class ImageFrame extends JFrame{
public ImageFrame(Image img){
setPreferredSize(new Dimension(540, 480));
setaImg(img);
ImagePanel somePanel = new ImagePanel(540, 480);
add(somePanel);
setVisible(true);
}
private Image aImg;
public Image getaImg() {
return aImg;
}
public void setaImg(Image aImg) {
this.aImg = aImg;
}
public class ImagePanel extends JPanel{
public ImagePanel(int width, int height){
setPreferredSize(new Dimension(width, height));
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(getaImg(), 0, 0, null); // see javadoc for more info on the parameters
}
}
}
}
I have ran it through the step through debugger and it stops at this line:
Image img=new ImageIcon(url).getImage();
But with no error, it just hangs forever.
I am totally confused as to why it isn't working on my system, and only my system. Any help would be GREATLY appreciated.
Works fine for me
Google's not blocking you are they? From memory you have something like 10,000 queries a day or something.
Try downloading the URL manually using the InputStream (URL.openStream()) and see if you're getting some kind of response other than an image binary.
UPDATED
After investigation, found to be a problem with Java 7 and IPv6 as documented here Downloading files using Java randomly freezes
Always start and update the GUI on the EDT. See Concurrency in Swing for more details.
g.drawImage(getaImg(), 0, 0, null); // see javadoc for more info on the parameters
That comment is very good advice, since a 4 char edit should fix the problem.
g.drawImage(getaImg(), 0, 0, this); // Observer is good for asynchronous image load
This is for a kiosk application where this message is not desired. It's odd because Mac doesn't display this message in either browser -- seems to only happen on Ubuntu.
Using this example applet on Ubuntu 10, Firefox 12, I was able to reproduce the message "Applet initialized," illustrated below. It doesn't appear to be from an overridden init(), and the super implementation is empty; I presume it's a feature of either the plug-in or the browser itself. Oddly, the message actually moves from one lower corner of the browser window to the other, as the mouse cursor approaches it.
For embedded use, consider starting the applet (or hybrid application) via java-web-start as shown in the example.
Addendum: Andrew's example produces the message "Applet started."
Seems like futzing to me, but if by 'status bar' you mean the little bar at the bottom of older browsers, try using Applet.showStatus("") at the end of init() or start().
Edit: Using the following command produces the expected result in appletviwer.
$ appletviewer NoMessageApplet.java
Code:
// intended only to show attributes - view in browser
// <applet code='NoMessageApplet' width=400 height=400></applet>
import java.awt.BorderLayout;
import javax.swing.*;
public class NoMessageApplet extends JApplet {
String noMessage = " Nobody Here But Us Chickens..";
JTextArea output;
#Override
public void init() {
try {
SwingUtilities.invokeAndWait( new Runnable() {
public void run() {
initGui();
}
});
} catch(Exception e) {
e.printStackTrace();
}
}
public void initGui() {
JPanel gui = new JPanel(new BorderLayout(5,5));
output = new JTextArea(5,20);
gui.add(new JScrollPane(output));
setContentPane(gui);
setMessage("initGui()" + noMessage);
}
#Override
public void start() {
setMessage("start()" + noMessage);
}
/** Both sets the message as the 'status' message &
appends it to the output control */
public void setMessage(final String message) {
SwingUtilities.invokeLater( new Runnable() {
public void run() {
output.append(message + "\n");
}
});
showStatus(message);
}
}
This is not a direct answer to your question but definitely a possible solution to your problem (Was a comment. Added as an answer as suggested by #Andrew Thompson):
If it is a kiosk application then why is there a status bar at all?
If you have control over the system where the application is used from (or where the browser is installed), you can either deactivate the status bar in the browser or make the browser to be displayed always in full screen mode.
Most kiosk applications operate this way.
FF13 fixed it (so does the most recent version of Chrome). Both now currently do not enable status bar's by default (they did when I made this initial post). Not quite an answer, but an answer that worked for me.
What is the proper way to dispose of SWT Shells? I have created some Dialogs with success following the template given in the Dialog API docs. The SWT API for Dialog says:
The basic template for a user-defined dialog typically looks something
like this:
public class MyDialog extends Dialog {
Object result;
public MyDialog (Shell parent, int style) {
super (parent, style);
}
public MyDialog (Shell parent) {
this (parent, 0); // your default style bits go here (not the Shell's style bits)
}
public Object open () {
Shell parent = getParent();
Shell shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
shell.setText(getText());
// Your code goes here (widget creation, set result, etc).
shell.open();
Display display = parent.getDisplay();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
return result;
}
}
The Dialogs I have created do not have their own taskbar icon on Windows, as I would expect for a Dialog. I now want to create some Shells, which if I understand correctly will receive their own taskbar entry on Windows?
In contrast to the directions given in the above API docs, I have also seen an article which seems to suggest that having a while loop as shown in the API docs is the wrong way to do it. The article instead suggests disposing the Shell by using the close event listener.
What is the correct way to dispose of SWT Shells (and while were on the topic, Dialogs as well)?
Hopefully I can help explain what's going on here.
Dialog is basically just a convenient class to subclass, because Shell itself is not supposed to be subclassed. You can create shells without using Dialog at all, if you want to. In this case, your MyDialog class is a class that others can use to open the same kind of dialog repeatedly.
This piece of code drives the SWT event loop as long as the shell is open (clicking the close button on the shell disposes the shell by default):
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
You have to call Display.readAndDispatch periodically to keep your SWT application from "locking up". Basically it causes all of the incoming events from the operating system (keyboard and mouse events, repaint events, etc.) to be correctly processed by your application. readAndDispatch basically takes an event from the application's event queue and invokes the correct listeners. In an Eclipse RCP application, the workbench is normally responsible for "pumping" the event loop and you don't have to mess with it. Here's a little more info about the event loop.
The purpose of "manually" pumping the event loop in this context is to prevent MyDialog.open from returning while the shell is not disposed, but still keep the application from "hanging". If your MyDialog.open method tried to wait for the shell to be disposed, but it didn't pump the event loop, your application would "lock up" because without the event loop running, there's no way for the shell to ever be notified that it should be disposed!
You can create shells without using this pattern. Here's an example of a very simple SWT application that opens a ton of shells all at once and keeps running as long as at least one of them is still open (I've omitted the package declaration and imports):
public class Shells {
private static int numDisposals = 0;
public static void main(String[] args) {
Display d = Display.getDefault();
for (int i = 0; i < 5; i++) {
Shell s = new Shell(d);
s.open();
s.addDisposeListener(new DisposeListener() {
#Override
public void widgetDisposed(DisposeEvent arg0) {
numDisposals++;
}
});
}
while (numDisposals < 5) {
while (!d.readAndDispatch()) {
d.sleep();
}
}
}
}
Note that I add a DisposeListener to each shell so I can take some action when the shell is closed. You can also use IShellListener to listen more directly for the close event and even actually prevent it (which you might want to do if the shell contains unsaved work, for example). Here's an annoying modification to the first program that starts 5 shells and randomly prevents you from closing them:
public class Shells {
private static Random r = new Random();
private static int numDisposals = 0;
public static void main(String[] args) {
Display d = Display.getDefault();
for (int i = 0; i < 5; i++) {
Shell s = new Shell(d);
s.open();
s.addShellListener(new ShellAdapter() {
#Override
public void shellClosed(ShellEvent e) {
boolean close = r.nextBoolean();
if (close) {
System.out.println("Alright, shell closing.");
} else {
System.out.println("Try again.");
}
e.doit = close;
}
});
s.addDisposeListener(new DisposeListener() {
#Override
public void widgetDisposed(DisposeEvent arg0) {
numDisposals++;
}
});
}
while (numDisposals < 5) {
while (!d.readAndDispatch()) {
d.sleep();
}
}
}
}
Hopefully this has helped make things more clear!
Edited to add: I'm not totally sure why you aren't getting a windows taskbar item for your shell, but I suspect it has something to do with the style flags you're passing into the shell's constructor. The shells in my example have no style flags and they all get a taskbar icon.