I have read about that when programming Java Swing, we should put these components into Java Event Queue, because Java Swing thread is not-thread safe.
But, when I use Event Queue, I don't know how to update component properties (for example : set text for label or change something..). Here is my code :
public class SwingExample {
private JLabel lblLabel;
SwingExample(){
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
lblLabel = new JLabel("Hello, world!", JLabel.CENTER);
frame.getContentPane().add(lblLabel); // adds to CENTER
frame.setSize(200, 150);
frame.setVisible(true);
}
public void setLabel(){
lblLabel.setText("Bye Bye !!!");
}
public static void main(String[] args) throws Exception
{
SwingExample example = null;
EventQueue.invokeLater(new Runnable()
{
public void run()
{
example = new SwingExample(); // ERROR : Cannot refer to non-final variable inside an inner class defined in different method
}
});
// sometime in the futures, i want to update label, so i will call this method...
example.setLabel();
}
}
I know, if I write SwingExample example = new SwingExample(); the error won't appear again, but if i use that, I cannot process example.setLabel later.
Please tell me about this error and how to fix this.
Thanks :)
By having your SwingExample instance as a field, you can reference it inside the inner classes without it being final.
public class SwingExample {
private JLabel lblLabel;
private static SwingExample instance;
SwingExample() {
// code omitted
}
public void setLabel() {
lblLabel.setText("Bye Bye !!!");
}
public static void main(String[] args) throws Exception {
EventQueue.invokeLater(new Runnable() {
public void run() {
instance = new SwingExample();
}
});
// ...
EventQueue.invokeLater(new Runnable() {
public void run() {
instance.setLabel();
}
});
}
}
Related
public class Interface extends JFrame
{
public Interface() throws InterruptedException
{
//windowsetup
pan = new MainPanel();
Thread t = new Thread(pan);
t.start();
add(pan);
addKeyListener(pan);
}
public static void main(String[] Args) throws InterruptedException
{
Interface proj = new Interface();
}
}
////////
public class MainPanel extends JPanel implements KeyListener, Runnable
{
public void paint(Graphics g)
{
//painting
}
public void run()
{
while(true)
{
this.repaint();
//other codes
try
{
Thread.sleep(10);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
I have a code that looks like this. When I press the run button in Eclipse, sometimes it works properly, but sometimes the there would be nothing in the window at all, nothing painted and keys doesn't work.
I heard that using threads in GUI might cause concurrency problems, and I wonder if this is the case, and what I should do to correct it. Thanks.
stackoverflow.com/questions/369823/java-gui-repaint-problem
I found that this is exactly my case, and the solutions worked.
Though it appears my understanding to Swing is yet too shallow, I must go over the tutorial.
I have 2 Java files, the first one is the main java code behind the program. And second is a jfx.Webview. I've been trying for forever to include the jfx.Webview in a JPanel that I have on the first Java file. I'm new to Java, and it's definitely not as easy as i thought. Please, if someone with a better understanding could explain to me the proper way to get this done, that would be of great help.
Here are the 2 Java files after some cleaning up:
public class Xzibit07 {
public static void main(String[] args) {
generateUI();
}
private static void generateUI(){
XzibitUI program = new XzibitUI();
program.setVisible(true);
program.setTitle("Xzibit");
ImageIcon logoIcon = new ImageIcon(new ImageIcon("Data/Images/Logo.jpg").getImage().getScaledInstance(program.logoLabel.getWidth(), program.logoLabel.getHeight(), Image.SCALE_DEFAULT));
program.logoLabel.setIcon(logoIcon);
program.logoLabel.setBounds((program.logoPanel.getWidth()/2 - program.logoLabel.getWidth()/2), 0, 0, 0);
ImageIcon settingsIcon = new ImageIcon(new ImageIcon("Data/Images/Settings.png").getImage().getScaledInstance((program.logoPanel.getHeight()/4), (program.logoPanel.getHeight()/4), Image.SCALE_DEFAULT));
program.settingsLabel.setIcon(settingsIcon);
program.getContentPane().setBackground(Color.WHITE);
program.logoPanel.setBackground(Color.WHITE);
}
}
And the second:
public class XzibitWeb implements Runnable {
public String webPage = "http://www.example.com";
public static void main(String[] args) {
SwingUtilities.invokeLater(new XzibitWeb());
}
#Override
public void run() {
JFXPanel jfxPanel = new JFXPanel();
Platform.runLater(() -> {
WebView view = new WebView();
jfxPanel.setScene(new Scene(view, 1024, 400));
view.getEngine().load(webPage);
});
}
}
I think you are trying to do this
https://docs.oracle.com/javase/8/javafx/interoperability-tutorial/swing-fx-interoperability.htm
From your code i think you are not adding the jfxPanel to the frame.
I am trying to change the text inside a jLabel from the main method, the reason for this is because there are conditions that I need to meet for the change to happen and it is not trigger based.
Code:
public class TheMain extends javax.swing.JFrame {
public TheMain() {
initComponents();
}
public void changeLabel1(){
SwingUtilities.invokeLater(new Runnable() {
public void run() {
jLabel1.setText("looo");
}
});
}
public void changeLabel2(){
SwingUtilities.invokeLater(new Runnable() {
public void run() {
jLabel2.setText("looo");
}
});
}
public static void main(String args[]) {
TheMain some = new TheMain();
if(condition){
some.changeLabel1();
}else{
some.changeLabel2();
}
}
}
I tried printing some stuff inside changelabel1 and changelabel2 just to check if they are successfully called and it did print but I'm guessing it is not possible to implement the UI changes inside them, or am I mistaken?
if(condition){
some.changeLabel1();
}else{
some.changeLabel2();
}
The above logice needs to be defined in TheMain class because that is where the label variables will be defined.
The main() method is just used to create the GUI. There should be no application logic in the main() method.
I'm trying to use a SwingWorker but for some reason at worker.execute(); I receive the following error:
"Syntax error on token "execute", Identifier expected after this
token"
That doesn't help much, it's a generic error, and no matter how stupid it might be, it's been torturing me for hours.. I've seen that moving SwingWorker somewhere else outside the class may fix it, but I don't understand how and why and why it should not work like this! Ugh!
public class App {
private App() { // CONSTRUCTOR
final int WINHSIZE = 2000;
final int WINVSIZE = 2000;
class Enjoy extends JPanel {
#Override
public void paintComponent(Graphics g) {
g.drawLine(0, 0, 2000, 2000);
}
class MyExecutor extends SwingWorker<Void,Void> {
#Override
protected Void doInBackground() {
return null;
}
#Override
protected void done(){ // runs on EDT
}
}
MyExecutor worker = new MyExecutor();
worker.execute(); // What the hell is going wrong here?
}
Runnable runner = new Runnable() {
#Override
public void run() {
JFrame f = new JFrame("Title");
JPanel panel = new Enjoy();
JScrollPane myScrollPane = new JScrollPane(panel);
f.add("Center", myScrollPane);
f.pack();
f.setVisible(true);
}
};
SwingUtilities.invokeLater(runner);
}
public static void main(String[] args) {
new App();
}
}
Thanks.
worker.execute(); must be inside some method, it can't be directly within the scope of your Enjoy class.
I have a dialog box to be shown but it is giving compilation errors. The compilation errors are given in the last part.
import javax.swing.*;
class SwingDemo {
SwingDemo() {
JFrame jfrm = new JFrame("A Simple Swing Application");
jfrm.setSize(275, 100);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel jlab = new JLabel(" Swing means powerful GUIs.");
jfrm.add(jlab);
jfrm.setVisible(true);
}
public static void main(String args[]) {
public void run() {
new SwingDemo();
}
}
}
The errors are:
Multiple markers at this line
- Syntax error on token "void", # expected
- Syntax error, insert "enum Identifier" to complete EnumHeaderName
- Syntax error, insert "EnumBody" to complete BlockStatements
Just replace your main function with this.
public static void main(String args[]) {
// Create the frame on the event dispatching thread.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new SwingDemo();
}
});
}
First of all, do you use an IDE?
Your run() method is inside your main() method. You don't need a run method anyway. Just instantiate from main() new SwingDemo(); and remove the run() function like this:
public static void main(String[] args) {
new SwingDemo();
}