I'm using this code
private void botaoGrafADMouseClicked(java.awt.event.MouseEvent evt) {
try {
boolean[] b=new boolean[8];
if (Caixa9.isSelected()) b[0]=true; else b[0]=false;
if (Caixa11.isSelected()) b[1]=true; else b[1]=false;
if (Caixa10.isSelected()) b[2]=true; else b[2]=false;
if (Caixa12.isSelected()) b[3]=true; else b[3]=false;
b[4]=false;b[5]=false;b[6]=false;b[7]=false;
final LineChartDemo1 demo = new LineChartDemo1("Leitura A/D",b,"outad.txt",4);
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
demo.setVisible(true);
} catch (IOException ex) {
Logger.getLogger(Comunicacao.class.getName()).log(Level.SEVERE, null, ex);
}
}
to call an graph interface. But, when I do this, every time I call the graph, it generates on new window and, if I close on of these windows, the whole program is closed.
I'd want to know what am I doing wrong. How Can I avoid this (I would post a printscreen, but, as new user, I can't, it is on http://i.stack.imgur.com/4JLxQ.png I think
Edit: Image
JFrame has a default close operation (i.e. what happens when you close the window using your window manager) of EXIT_ON_CLOSE. Use JFrame.setDefaultCloseOperation to set a different value.
I don't know what the class LineChartDemo1 is, but you could probably set it as the content of a JDialog and call setDefaultCloseOperation (JDialog.DISPOSE_ON_CLOSE) on each dialog. This way, when the user closes the dialog, only that window will close, the others will remain open.
I created a new netbeans JFrame and made reference to it like this:
InterfaceGrafico minhaInterface = new InterfaceGrafico("Leitura I/O",b,"outio.txt",8);
where the arguments where the same to generate the graph. In this "InterfaceGrafico" class:
public InterfaceGrafico(final String title,boolean[] b, String nomeArquivo, int col) {
try {
initComponents();
final LineChartDemo1 demo = new LineChartDemo1("Leitura I/O", b, "outio.txt", 8);
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
demo.setVisible(true);
} catch (IOException ex) {
Logger.getLogger(InterfaceGrafico.class.getName()).log(Level.SEVERE, null, ex);
}
}
That means, I just shifted the code to another JFrame. I also commented the public void run method . Now I can close each graph generated without closing the whole application and the other generated graphs. In the "LineChart1" class, I added this
public void windowClosing(final WindowEvent evt){
if(evt.getWindow() == this){
dispose();
}
}
Related
I'm currently working on a game that's based on a client-server architecture. What basically happens is that one player can create a lobby that others can connect to by providing IP address and port number (so, actually basic Java Sockets). Before the actual game is started, all players are first placed inside a lobby which consists of a JLabel displaying the player count and a JTextArea providing information about people joining or leaving the lobby. Everytime a new player connects or someone leaves the lobby, the host pushes out notifications to the clients for updating their UI correspondingly.
The problem is now the following: I want the lobby to be displayable in fullscreen if the user likes (which is also implemented already using keybindings/Input-/Actionmaps). However, when a user changes from window to fullscreen or back the current frame has to be disposed and as a consequence reset to the initial lobby state. I originally wanted to solve this using the class LobbyState which stores all relevant data to be restored. However, somehow this is not working as the frame still displays the initial state of the lobby when changing "window-mode".
To give you an insight into the code, this is the relevant code of the Lobby class:
private int playerCount = 1;
private boolean isHost;
public Lobby(Integer windowState, Image image, Boolean isHost, LobbyState lobbyState) {
this.isHost = isHost;
setDefaultCloseOperation(EXIT_ON_CLOSE);
setTitle("Lobby");
setExtendedState(MAXIMIZED_BOTH);
setSize(screenDim);
setMinimumSize(new Dimension(800, 400));
setIconImage(image);
if (windowState == 1) {
setUndecorated(true);
} else {
setUndecorated(false);
}
setResizable(true);
contentPane.setLayout(null);
setLayout(null);
contentPane.getInputMap(KeyBindings.AFC).put(KeyStroke.getKeyStroke("F11"), "lobby_fullscreen");
contentPane.getActionMap().put("lobby_fullscreen", new EnterFullscreen(this, this.isHost, new LobbyState(playerCount, getLobbyHistory())));
contentPane.setBackground(new Color(253, 205, 136));
setContentPane(contentPane);
loadComponents();
loadBounds();
addActionListeners();
if (lobbyState != null) {
lblPlayerCount.setText("" + lobbyState.getPlayerCount());
txtLobbyHistory.setText(lobbyState.getLobbyHistory());
}
setVisible(true);
}
My first assumption why F11 triggers the creation of a Lobby with the initial state instead of the current state is, that the ActionMap is created when playerCount is still 1 and getLobbyHistory() doesn't return anything because there actually still is no lobby history. If this is really the problem, is there any possibility to tell the ActionMap to re-read the values of playerCount and getLobbyHistory() whenever F11 is pressed? Would I have to remove the current ActionMap and add a new one or is there a more elegant way to solve this?
In case this is of any interest, this is the code that currently performs the toggle between window and fullscreen application:
public class EnterFullscreen extends AbstractAction{
private static final long serialVersionUID = 1773898497666165938L;
private JFrame frame;
private boolean isHost;
private LobbyState lobbyState;
private Class<?> frameType;
private Constructor<?> c;
public EnterFullscreen(JFrame frame, boolean isHost, LobbyState lobbyState) {
this.frame = frame;
this.isHost = isHost;
this.lobbyState = lobbyState;
try {
frameType = frame.getClass();
if (frameType.equals(Lobby.class)) {
c = frameType.getConstructor(Integer.class, Image.class, Boolean.class, LobbyState.class);
} else {
c = frameType.getConstructor(Integer.class, Image.class, Boolean.class);
}
} catch (SecurityException | NoSuchMethodException e) {
e.printStackTrace();
}
}
#Override
public void actionPerformed(ActionEvent e) {
try {
frame.setVisible(false);
if (frame.isUndecorated()) {
if (frameType.equals(Lobby.class)) {
c.newInstance(0, frame.getIconImage(), isHost, lobbyState);
} else {
c.newInstance(0, frame.getIconImage(), isHost);
}
} else {
if (frameType.equals(Lobby.class)) {
c.newInstance(1, frame.getIconImage(), isHost, lobbyState);
} else {
c.newInstance(1, frame.getIconImage(), isHost);
}
}
frame.dispose();
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException e1) {
e1.printStackTrace();
}
}
}
I'd really appreciate any input on how to solve this and how one would achieve something like this properly. If you feel like there's any missing information or code to solve this, please let me know and I'll try to provide that as soon as possible.
I am writing 3d rendering module for an AWT/Swing application.
To provide good FPS, I can't draw using Swing/AWT methods and graphics. Instead, I obtain the Drawing Surface from the Canvas element, and then render directly to it. Something like this:
public class Window {
private Component canvas;
private JAWTDrawingSurface ds;
public static final JAWT awt;
static {
awt = JAWT.calloc();
awt.version(JAWT_VERSION_1_4);
if (!JAWT_GetAWT(awt))
throw new AssertionError("GetAWT failed");
}
public void lock() throws AWTException {
int lock = JAWT_DrawingSurface_Lock(ds, ds.Lock());
if ((lock & JAWT_LOCK_ERROR) != 0)
throw new AWTException("JAWT_DrawingSurface_Lock() failed");
}
public void unlock() throws AWTException {
JAWT_DrawingSurface_Unlock(ds, ds.Unlock());
}
public void Init2()
{
this.ds = JAWT_GetDrawingSurface(canvas, awt.GetDrawingSurface());
try
{
lock();
// Create GL Capabilities
unlock();
}
}
It works fine when I call it the first time.
But when I hide the canvas for any reason (for example minimizing window or displaying another panel instead of Canvas), the ds variable remains the same, but it doesn't work after that.
Basically, even if I make sure I call the variable only when it is visible and on top - any call using ds will throw an exception. For example lock() function stops working.
I'm wondering why's that?
Also I tried to basically obtain a new DS if I minimize and then maximize the window again, but this also doesn't work - the new DS address is returned as it should, but I can't use that new object just as I couldn't use the original one.
There's probably something stupid I'm missing here, but I can't figure out what.
Please help me sort this out. Thank you!
The solution:
When the Canvas is hidden, call eglMakeCurrent(eglDisplay,EGL_NO_SURFACE,EGL_NO_SURFACE,EGL_NO_CONTEXT) to unbind the current context.
When you need to start drawing again, you need to do something like this:
public void Reinit()
{
System.err.println("Context Reinit()");
this.ds = JAWT_GetDrawingSurface(canvas, awt.GetDrawingSurface());
try
{
lock();
try
{
JAWTDrawingSurfaceInfo dsi = JAWT_DrawingSurface_GetDrawingSurfaceInfo(ds, ds.GetDrawingSurfaceInfo());
JAWTX11DrawingSurfaceInfo dsiWin = JAWTX11DrawingSurfaceInfo.create(dsi.platformInfo());
this.display = dsiWin.display();
this.drawable = dsiWin.drawable();
eglDisplay = eglGetDisplay(display);
surface = eglCreateWindowSurface(eglDisplay,fbConfigs.get(0),drawable,(int[])null);
eglMakeCurrent(eglDisplay,surface,surface,context);
GLES.setCapabilities(glesCaps);
JAWT_DrawingSurface_FreeDrawingSurfaceInfo(dsi, ds.FreeDrawingSurfaceInfo());
}
finally
{
unlock();
System.err.printf("Unlock \n");
}
}
catch (Exception e)
{
System.err.println("JAWT Failed" + e.getMessage());
}
}
As You can see, I re-create the display and surface, but I use the previously created context for rendering, without needing to re-create it.
I'm trying to create a button in game where the background color will go from light_gray to dark_gray. However when the application relaunches I have to re select the button to get the color back to dark_gray.
How would I have it so that it saves the color when the application is relaunched?
My code is very simple and is just an action listener on the button which then changes the bg color of selected items.
Ok, I have now had the chance to allow it to create the properties file but one doesn't know how one could store the data. I've seen people have stuff such as 'properties.setProperty("Favorite sport", "Football");'
But how could one have this so that it stores the bg color?
windowDark.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae)
{
try {
Properties properties = new Properties();
properties.setProperty();
File file = new File("DarkTheme.properties");
FileOutputStream fileOut = new FileOutputStream(file);
properties.store(fileOut, "Dark theme background colour");
fileOut.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
The java.util.prefs Preferences API is well suited for storing persistent preference data for user applications running on the desktop.
Here's an example how you can use it to store and retrieve persistent background color settings:
import java.awt.Color;
import java.util.prefs.Preferences;
public class MyPrefs {
private static Preferences preferences =
Preferences.userRoot().node("myappname.ColorPreferences");
public static void storeBackground(Color background) {
preferences.putInt("background", background.getRGB());
}
public static Color retrieveBackground() {
// Second argument is the default when the setting has not been stored yet
int color = preferences.getInt("background", Color.WHITE.getRGB());
return new Color(color);
}
}
To call it, use something like:
public static void main(String[] args) {
System.out.println("Background: " + retrieveBackground());
storeBackground(Color.RED);
}
You can store the color as an int value in the properties file, as follows:
windowDark.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
getProperties().setProperty("color", Integer.toString(getColor().getRGB()));
}
});
Have the properties as a member of the window this button is in, or even better, in some general location of the application (the class with the main() perhaps ?), and access it with getProperties().
When you need to use the color, parse the string:
Color color = new Color(Integer.parseInt(getProperties().getProperty("color")));
Don't save the properties file on each button click, instead, do so when the application is about to exit:
mainWindow.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
mainWindow.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
try {
File file = new File("DarkTheme.properties");
FileOutputStream fileOut = new FileOutputStream(file);
getProperties().store(fileOut, "Dark theme background colour");
fileOut.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
mainWindow.dispose();
}
}
});
The change done in memory will be disposed once the application is terminated. If you want to persist some data (in this case, the background color), then you need to store is somewhere, e.g. file, database, etc.
For a simple application, storing your data in a file will be practical.
To do this, you will need to:
- when application starts, read the file, and apply the color specified in the file
- while the application is running and user changes the color, save the color to the same file
To deal with file, you will need to use File, FileReader, and FileWriter classes (all are in java.io package).
I read here , but if the xml file changes the jtree does not reload /refreshes
how to create a function for refresh / reload Jtree
I try to write code :
refreshAction = new AbstractAction("Refresh", IconFactory.getIcon("delete", IconFactory.IconSize.SIZE_16X16)) {
public void actionPerformed(ActionEvent e) {
XMLTree xmlClass = null;
((DefaultTreeModel) xmlClass.getModel()).reload();
System.out.println("Refresh");
}};
but i got the error : java.lang.NullPointerException
I added a new Action to popup in getJPopupForExplorerTree(). You'll probably want to re-factor xmlFile out of the XMLTree constructor; I've hard coded it for expedience below:
popup.add(new AbstractAction("Reload") {
public void actionPerformed(ActionEvent e) {
System.out.println("Reload");
try {
root = getRoot("xml.xml");
setModel(new XMLTreeModel(root));
} catch (Exception ex) {
ex.printStackTrace(System.err);
}
}
});
this is most complex code, probably
read tutorial about JTables DefaultTableModel (good described concept and logics for DefaultXxxModel is similair / the same)
read tutorial about JTree
read tutorial about Concurency in Swing,
especially description about SwingWorker
in your case better (sorry for that) would be create an new instance for DefaultTreeModel, fills data by using SwingWorker, add new model to the visible JTree,
by replacing model you'll lost all changes in the current JTree
I dont know the spesific code but you can try this
refreshAction = new AbstractAction("Refresh", IconFactory.getIcon("delete", IconFactory.IconSize.SIZE_16X16)) {
public void actionPerformed(ActionEvent e) {
DefaultTreeModel myTreeModel = (DefaultTreeModel) xmlClass.getModel();
myTreeModel.reload();
revalidate();
repaint();
}};
hi i have a full screen program which i dont want people to close unless they have a password i have this code at the moment
public void windowClosing(WindowEvent arg0)
{
System.out.println("HERE");
String inputValue = JOptionPane.showInputDialog("Please input the closeword");
if (inputValue != "closeplz")
{
}
}
in the if statement i want it to stop the method so that the program doesent close. any help would be greatly aprecheated thanks ste
You have to call
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
on (or within) the JFrame instance. Then the frame will not close unless you do it manually, though windowClosing() will still be called. Inside it, you can then conditionally call
System.exit(1);
which will end the application. Be sure to do any necessary cleanup first.
Check out Closing an Applicaton for a simple class to help you with this. You would need to provide the custom close action that prompts the user for the password.
Using your simple example the code would be:
Action ca = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
JFrame frame = (JFrame)e.getSource();
String inputValue = JOptionPane.showInputDialog("Please input the closeword");
if (! inputValue.equals("closeplz"))
{
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
}
}
};
CloseListener cl = new CloseListener(ca);