I've made a gui for my program and used
UIManager.put("Button.background", new Color(0,0,0));
UIManager.put("JButton.background", new Color(0,0,0));
to make the buttons appear black. Unfortunately, this doesn't work sometimes. Without modifying the code, it will work when I run it one time and wont work another time.
The following image is the same button in the same program after several times I ran it. This happens about 1 in 4 times I run the program.
(left button is correct and the right one is what sometimes happens while running)
Also, other things like
UIManager.put("control", new Color(15,0,0));
are loading properly. Never had a problem with it and it's loaded at the same time and same format.
EDIT: Here's a sample code where the button colors aren't loading at all while the background and other things are. They are loaded the same exact way and there are no compilation or run errors.
import java.awt.*;
import javax.swing.*;
import javax.swing.UIManager.*;
public class gtst
{
public static void main(String[] args) throws Exception
{
UIManager.put("Button.background", new Color(1,1,1));
UIManager.put("JButton.background", new Color(1,1,1));
UIManager.put("control", new Color(0,0,0));
UIManager.put("text", new Color(255,220,0));
Frame batFrame = new JFrame("nananananna Batman!");
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels())
{
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
String username = JOptionPane.showInputDialog(batFrame, "Enter something...:");
}
}
How I usually do this is I make a button as a seperate JButton variable and then add that to my panel. Then to set the color of the button I use the code:
myButton.setBackground(Color.BLACK);
and that usually does the trick.
Try using the following code after you have made the changes in the UIManager:
SwingUtilities.updateComponentTreeUI(<your_root_ui_componenet>);
After days of non stop trial and error, I figured out that apparently in my program the MySQL connection was causing the problem. If the MySQL connection was initiated at the start of the program and the color changes were too this cause some sort of a problem (maybe lag?) and the colors wouldn't always load. Maybe it's a problem with the MySQL driver or something else, not sure, but to fix it I just made it connect to MySQL when it needed the connection rather than at the program start.
I'm not sure why the colors didn't load at all in the example I provided.
Related
I am writing a Java application for image analysis which at one point opens ImageJ with
ImageJ ij = new ImageJ();
and also opens a Windows containing an ImagePlus.
Now, whenever one closes ImageJ first, the ImagePlus will not close when pushing the close button. The other way around works, however in both cases an exception is thrown after closing ImageJ:
java.lang.reflect.InvocationTargetException
at java.awt.EventQueue.invokeAndWait(EventQueue.java:1288)
at java.awt.Window.doDispose(Window.java:1209)
at java.awt.Window.dispose(Window.java:1147)
at ij.ImageJ.run(ImageJ.java:784)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalArgumentException: null source
at java.util.EventObject.<init>(EventObject.java:56)
at java.awt.AWTEvent.<init>(AWTEvent.java:337)
at java.awt.event.InvocationEvent.<init>(InvocationEvent.java:285)
at java.awt.event.InvocationEvent.<init>(InvocationEvent.java:174)
at sun.awt.X11.XBaseMenuWindow.dispose(XBaseMenuWindow.java:907)
...
I don't know whether it is related as it happens in both cases.
Any suggestions on how to force ImageJ to close all its windows?
The exception
This happens when using OpenJDK 7 on Linux. The exception is fixed in Java 8.
Also: note that that exception is not the actual cause of the quitting issue you are seeing.
The disposal problem
ImageJ 1.x's application disposal is a convoluted mess. (See this news post for some technical discussion.) It was really intended primarily to run as a standalone application, and is mostly tested with the exitWhenQuitting flag set to true such that the JVM shuts down upon closure of the main window. So it is not surprising that using ImageJ in a different fashion results in hanging image windows.
I have tested various workarounds—e.g.:
ij.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(final WindowEvent e) {
// dispose all image windows
for (final int id : WindowManager.getIDList()) {
final ImagePlus imp = WindowManager.getImage(id);
if (imp == null) continue;
final ImageWindow win = imp.getWindow();
if (win != null) win.dispose();
}
// dispose all other ImageJ windows
for (final Window w : WindowManager.getAllNonImageWindows()) {
w.dispose();
}
}
});
But none of them work as one might hope. It cost me weeks of development and experimentation to make quitting work as we wanted in ImageJ2, according to the news posted linked above.
Here is some code using ImageJ2 that almost behaves the way you want:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
import net.imagej.ImageJ;
public class IJDispose {
public static void main(final String... args) {
final ImageJ ij = new ImageJ();
ij.ui().showUI();
final JFrame frame = new JFrame("Hello");
final JButton b = new JButton("Close ImageJ");
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(final ActionEvent e) {
ij.getContext().dispose();
}
});
frame.getContentPane().add(b);
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
After launching it, press Shift+B to open the Blobs sample image. Then click the "Close ImageJ" button from the non-ImageJ frame. You'll see that the ImageJ main window and the image window dispose as desired (using this code from ImageJ Legacy).
However, there are (at least) three problems:
This example does not hook up the ij.getContext().dispose() call to the actual ImageJ1 UI window closing event. And doing that would not be trivial (I say without having dug deeply in this code recently).
After disposing ImageJ, as well as the extra JFrame, the JVM is supposed to shut down. We put a lot of effort into making it do so, actually. But it actually doesn't with the current version of ImageJ, presumably due to some undisposed resource(s) somewhere. This is a bug.
Clicking the X on the main ImageJ window shuts down the entire JVM, because ImageJ1's exitWhenQuitting flag gets set to true. You could toggle it back to false yourself, but this is actually tricky due to class loading issues relating to the fact that ImageJ2 patches ImageJ1 at runtime using Javassist.
The next question is: How badly do you really need this to work?
*I'm sorry for all of the trouble I may have caused you guys.
So, I am extremely new to programming with just a little experience in Java and Python. I was trying to make a program that would open a frame. In this frame there would be a button. When clicked, this button would play a song. I used a "recommended" code from YouTube. The code would begin to run, and then just stop. No frame would ever even appear. I showed it to a more experienced friend of mine. He said that the exact code ran just fine on his computer. I then sent him a screenshot of my project displayed on eclipse. He said that my JRE seemed to be missing some files. I tried a code that would just create a window, but it had the same problem. I am not sure what the JRE is, but I currently have JRE7. I don't know what I should do to fix this. Please help.
Error List
Severity and Description Path Resource Location Creation Time Id
The public type TopLevelWindow must be defined in its own file TGProject/src Frame.java line 4 1390698271752 73
The type TopLevelWindow is already defined TGProject/src TopLevelWindow.java Unknown 1390699351785 77
The method show(boolean) from the type Component is deprecated TGProject/src sound.java line 16 1390702839525 78
A link to the what my eclipse shows.
http://gyazo.com/3afdfa4f6750420f4e46deec40389340
A link to my Java file.
http://gyazo.com/257481d4ae9e2bb1d0ca93415a6c547e
Code for music
import java.awt.event.*;
import javax.swing.*;
import sun.audio.*;
import java.io.*;
public class sound {
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.setSize(200,200);
JButton button = new JButton("Click me");
frame.add(button);
button.addActionListener(new AL());
//this is outdated, but should still work
frame.show(true);
}
public static class AL implements ActionListener{
public final void actionPerformed(ActionEvent e) {
music();
}}
public static void music()
{
AudioPlayer MGP = AudioPlayer.player;
AudioStream BGM;
AudioData MD;
ContinuousAudioDataStream loop = null;
try{
BGM = new AudioStream(new FileInputStream("Jambi.mp3"));
MD = BGM.getData();
loop = new ContinuousAudioDataStream(MD);
}catch(IOException error) {}
MGP.start(loop);
}
}
Code for Frame
import java.awt.*;
import javax.swing.*;
// Create a simple GUI window
public class TopLevelWindow {
private static void createWindow() {
//Create and set up the window.
JFrame frame = new JFrame("Simple GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel textLabel = new JLabel("I'm a label in the window",SwingConstants.CENTER);
textLabel.setPreferredSize(new Dimension(300, 100));
frame.getContentPane().add(textLabel, BorderLayout.CENTER);
//Display the window.
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
createWindow();
}
}
Error 1
The public type TopLevelWindow must be defined in its own file
You either need to change.
public class TopLevelWindow {
To:
class TopLevelWindow {
Or do as reported and declare a new class for TopLevelWindow
Error 2
The type TopLevelWindow is already defined
I'm not sure what that means, but it might be solved by fixing the first problem.
Warning 3
The method show(boolean) from the type Component is deprecated
For any deprecation warning, go to the relevant method in the Java Docs. They should give details about what to use instead.
Tips
Compile often and ask as soon as you have a single error you do not understand.
Don't try to run code that shows problems in that window. Only experts should even try that.
You catch more flies with honey than with vinegar. Don't take the tone you did with Jayan, even if you think they are being harsh. People help for free, so have little time for questions that do not come up to standard. It might have been better to explain to the person that the question had now changed. Perhaps that would have made no difference to them, but either way, adding that kind of reply discourages everyone from helping.
"I used a "recommended" code from YouTube." Don't use YouTube videos to learn programming. They are often old, and in this case, they are using classes in the sun package for which there were better replacements since Java 1.3.
If you're really that new to programming, I would suggest to use an IDE (development environment) like for instance Netbeans or Eclipse and create a new JFrame form. You can then use the design view to graphically design your interface, IE drag your button on the screen. No need to go around programming frames. All you need to code is the implementation; what happens after you click the button.
After you posted the code, I had another look and this is what I've found:
Both classes have main methods. I ran both and each opened up a different window for me. Typically, you'll only want one main method. It's the main method! It's the starting point of your program and you can of course only have one starting point. At this time, your program is going to do two different things depending on what main method you run.
Still, this isn't your issue, because both mains are running for me. I think you must have the wrong version of java or something?
What I think you did is you pasted all that code into a file that wasn't called exacly "TopLevelWindow". If so, do that. I think your problem will go away.
Remember to only have one class per file, (barring inner classes; not something to concern yourself with as a beginner).
In the project I am currently working on I have several pieces of information that I would like to make visible via Jlabel. There are a few buttons and textfields elsewhere in the GUI that allow for altering said information I would like to update the JLabel but the text never changes, or updates upon startup.
I have attempted to use concurrency to update the labels, as suggested in other questions on this site, but I have had no luck with the labels updating. The concurrency does work with updating textfields and comboBoxes as needed.
The current iteration of my code looks as follows,
The JFrame
//// This is a snippet from the JFrame
public void start()
{
this.setSize(900, 700);
this.setVisible(true);
devicePanel.populateDeviceDefinitions();
updateServiceInfo();
updateCommandInfo();
startUpdateTimer();
}
public void updateServiceInfo()
{
EventService service = JetstreamApp.getService();
generalPanel.updateServiceInfo(service.getBaseUri(),
service.getAccessKey(), String.valueOf(service.getWindowTime()));
}
public void updateCommandInfo()
{
JetstreamServiceClient client = JetstreamApp.getClient();
generalPanel.updateCommandInfo(client.getBaseUri(), client.getAccessKey());
}
The JPanel named generalPanel
//// This is a snippet from the generalPanel
//// All of the variables in the following code are JLabels
public void updateServiceInfo(String baseUrl, String accessKey,
String windowTime)
{
serviceUrl.setText(baseUrl);
serviceAccessKey.setText(accessKey);
serviceWindowTime.setText(windowTime);
}
public void updateCommandInfo(String baseUrl, String accessKey)
{
commandUrl.setText(baseUrl);
commandAccessKey.setText(accessKey);
}
The labels start with an Empty string for their text and upon window start it is intended that they be updated by grabbing the information from the relevant sources. Can I please have some insight as to why the JLabels never update and display their information?
How did you create the JLabel? If the text starts out as "", and you've created it with new JLabel(""), the width of the JLabel may be initialized to 0 and then none of your text would show up when you update it. I believe I've had that sort of problem in the past. As a test, try using new JLabel("aaaaaaaaaa") or some longer string to create the label, then setText(""); then later, when you setText(somethingElse), see if that causes text to show up. If it does, then the width is probably the problem and you can work on it from there. – ajb 19 mins ago
This comment is the actual answer, when creating a JLabel with an empty string as the text the label's dimensions do not get set properly when using WindowBuilderPro. My labels did exist, and were being updated with the code provided in my question but the labels were not visible.
Starting with a label that has text in it, then setting the text to an empty string works properly.
The method paintImmediately() can be used to cause a Swing component to get updated immediately. after setText(), you should call paintImmediately() like below.
jLabel.setText("new text")
jLabel.paintImmediately(jLabel.getVisibleRect());
You should try to call revalidate() or repaint() on the component that contains your JLabels.
Cheers
I have a simple java application that uses JOGL. When I run it from eclipse, and then close the application window, javaw.exe remains running. Here is the the relevant code:
public class App {
private Display mDisplay;
private Shell mShell;
private GL4 mGl;
private int mProgramId;
private int mVsId;
private int mFsId;
// ...
public void start() {
if (!initialize()) {
return;
}
while (!mShell.isDisposed()) {
if (!mDisplay.readAndDispatch()) {
mDisplay.sleep();
}
}
destroy();
}
private void initialize() {
mDisplay = new Display();
mShell = new Shell(mDisplay);
// some SWT and opengl initialization code, which is irrelevant for this issue
// (at least I think so)
// getting GLProfile, GLContext, GL4 etc.
final String vsText = ResourceManager.getShaderText(vsPath);
final String fsText = ResourceManager.getShaderText(fsPath);
mVsId = mGl.glCreateShader(GL4.GL_VERTEX_SHADER);
mFsId = mGl.glCreateShader(GL4.GL_FRAGMENT_SHADER);
mGl.glShaderSource(mVsId, 1, new String[] { vsText }, null, 0);
mGl.glCompileShader(mVsId);
mGl.glShaderSource(mFsId, 1, new String[] { fsText }, null, 0);
mGl.glCompileShader(mFsId);
mProgramId = mGl.glCreateProgram();
mGl.glAttachShader(mProgramId, mFsId);
mGl.glAttachShader(mProgramId, mVsId);
// bind a constant attribute location for positions of vertices
mGl.glBindAttribLocation(mProgramId, 0, "in_Position");
// bind another constant attribute location, this time for color
mGl.glBindAttribLocation(mProgramId, 1, "in_Color");
mGl.glLinkProgram(mProgramId);
// here error code is 0x0 (no error)
int error = mGl.glGetError();
mShell.open();
return true;
}
private void destroy() {
// here error code is 0x502 (GL_INVALID_OPERATION)
int error = mGl.glGetError();
mGl.glDetachShader(mProgramId, mFsId);
mGl.glDetachShader(mProgramId, mVsId);
mGl.glDeleteShader(mFsId);
mGl.glDeleteShader(mVsId);
mGl.glDeleteProgram(mProgramId);
mDisplay.dispose();
}
}
I commented out all rendering code and most other opengl/JOGL related calls (besides getting GLProfile, GLContext, GL4 and everything listed in this sample) and this problem persists.
Generally, the application works fine, shaders compile and link without problem (I used validation which I didn't display in this sample) and it displays what it needs to. The only problem is that javaw.exe remains running after I close the application window (by pressing the x in the corner of the window).
This issue is removed only if I comment out mGl.glCompileShader(mVsId); and subsequent lines. If I leave this line, javaw.exe will remain running, so I guess the problem is related to shader initialization/destruction code.
Also, glGetError() returns 0 (no error) at the end of initialize() and 0x502 (GL_INVALID_OPERATION) at the beginning of destroy(). There is only the main loop in between and no opengl calls that I know of, since, for testing, I commented out all rendering code.
Any ideas?
Edit 2012-10-03:
I still don't know what the problem is, but since I updated my graphic card drivers, 'javaw.exe' terminates as it should after application is closed. I have AMD Radeon HD 6870. My current driver version is 8.982 from 2012-07-27, and I can't remember what the last version was, but I believe it was from january 2011 or so.
However, glGetError() still returns 0x502 at the beginning of destroy, so I guess there is still something wrong.
Assuming you use JOGL from jogamp.org, pls use either our SWT GLCanvas
or our NEWTCanvasSWT.
The latter is preferred due to custom GLCapabilities, pls check API doc.
This given plus you are doing everything SWT related on the SWT thread (read
linked unit tests), IMHO it should work - at least our unit tests.
Since you mentioned after an update (GPU/driver) your troubles ceased to exist,
it might have been a driver problem.
Now to your GL error. Trace GL errors can be simply done by setting the system property 'jogl.debug.DebugGL', i.e. on the commandline "-Djogl.debug.DebugGL".
This will install the debug pipeline for your GL object automatically and checks for GL error, which will throw an GLException if appear.
You can also trace via the property 'jogl.debug.TraceGL'.
I don't know if this is relevant or not, but may help someone I guess so I'm gonna share it here. Keep in mind I'm just a hobbyist getting started in Java SWT.
I made a simple application in Eclipse IDE using the Java SWT library. I made a ''Quit'' button in my main Window shell that when pushed calls this :
quitBtn.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
shell.getDisplay().dispose();
System.exit(0);
}
});
After exporting the .jar file to Desktop, I converted it to a .exe file with LaunchJ4 wrapper and check the "Allow only a single instance of the application" in the Single instance tab using the singleR3XPlayer mutex.
When I would close the .exe file with the "Quit" button, everything was fine and the javaw.exe would terminates. But when I closed the shell with the X button on the top-right window, javaw.exe would remains running. I figured that out when I tried to delete the .exe file (Windows "Used file, still open in Java(TM) Platform SE binary, close the file and retry" type of error pop-up) and as I couldn't open another instance of the file after closing it with the X button (because of the Single instance mutex). Also, multiple instances of javaw.exe would remains running if I would execute a few of the .jar file (even after closing them, but only with the X and not the "Quit" button).
I figured out closing the window with the X button would only dispose of the shell and not exit the program. But pressing the "Quit" button would because it called System.exit(0). So I did this :
// SWT Event Loop
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
// To make sure javaw.exe terminates when Window is closed
if (shell.isDisposed()) {
System.exit(0);
}
Hence, after my SWT Event loop is done (shell.isDisposed() == true), I made sure System.exit(0) would be called. This way, javaw.exe is terminated either way.
I don't know how SWT works and I don't know if that's the proper way to do it but it ensures javaw.exe is terminated once the application closes.
Hope that helps.
I am trying to create my first GUI application using (Java + Eclipse + Swing). This is my code:
import java.awt.*;
import javax.swing.*;
public class HelloWorldSwing extends JFrame {
JTextArea m_resultArea = new JTextArea(6, 30);
//====================================================== constructor
public HelloWorldSwing() {
//... Set initial text, scrolling, and border.
m_resultArea.setText("Enter more text to see scrollbars");
JScrollPane scrollingArea = new JScrollPane(m_resultArea);
scrollingArea.setBorder(BorderFactory.createEmptyBorder(10,5,10,5));
// Get the content pane, set layout, add to center
Container content = this.getContentPane();
content.setLayout(new BorderLayout());
content.add(scrollingArea, BorderLayout.CENTER);
this.pack();
}
//============================================================= main
public static void main(String[] args) {
JFrame win = new HelloWorldSwing();
win.setTitle("TextAreaDemo");
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
win.setVisible(true);
}
}
The code was taken from here.
When I run the application from Eclipse the expected window appears (So, it's good. I see what I want to see). However, when I try to close the window or try to write something in the text area the program freezes. The OS writes me that program is not responding (I try it on Ubuntu).
Can anybody help me to find the reason of the problem?
Thank you in advance for any help.
I'm sure this doesn't have to do with the code, as others have found the code runs just fine on their machines - which points to a machine specific issue. From within Eclipse, make sure it is setup to use the expected JDK/JRE. However, before worrying about how Eclipse is handling your situation, I'd run things by hand first - especially since you've got a very simple class.
I would check to ensure that you're using the expected compiler and runtime. On Linux:
which javac
which java
If they're both what you expect, do the following:
javac HelloWorldSwing.java
java HelloWorldSwing
If you get a similar problem, then you know it's not the Eclipse configuration and it's something else. If you're not using the latest JDK, upgrade to the latest. If you're already at the latest, it could be a display driver. Do other JAVA swing programs work on this computer? I'm sure you could find some on the net, download an app already packaged as a jar and try running it.
did you try using the eventdispatcherthread to view the JFrame?
something like:
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
public void run(){
createAndViewJFrame();
}
});
}
public void createAndViewJFrame(){
JFrame win = new HelloWorldSwing();
win.setTitle("TextAreaDemo");
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
win.setVisible(true);
}
then your frame would be shown by the swing dispatcher thread.
hope it helped, although im just guessing...
Update: as commenters pointed you i f**ed up the invokeLater() call. I just edited this post to correct that. Thanx go to yishai & willcodejavaforfood for pointing it out!
frank
You need to catch the exit event and
respond with a System.exit( 0 );
You should be able to find that in
most swing examples online.
wrong stuff... sorry... coffee... argh....