Filthy Rich Clients

Chet Haase, Romain Guy

Mentioned 8

This book is about building better, more effective and cooler desktop application using Java tools. Graphical effects, especially animated ones, can be overdone creating an application that would overload the senses. The authors show how to enrich the graphics and animate effectively.

More on Amazon.com

Mentioned in questions and answers.

In my current project we have to develop a good looking desktop based application in java.

Currently, we have a very basic desktop application written in swing and team does not have good swing knowledge. Can we create a very good looking UI in swing?

Should we use JavaFX for creating the desktop application?

What are other alternatives to do this?

Swing is very flexible with regards to look-and-feel and you can certainly make very good looking applications with Swing.

I recommend the book Filthy Rich Clients by Chet Haase and Romain Guy if you want to learn how to make nice Swing GUI applications.

Are Swing applications really used nowadays? I don't find a place where they are used. Is it okay to skip the AWT and Swing package (I learned a bit of the basics though)?

Check out Filthy Rich Clients. It explains some of the history of AWT and Swing. Swing, being a lightweight alternative (successor) to most of the AWT classes.

I would like to do a "sexy" / user-friendly / appealing GUI in java. Swing is a limited in terms of "skin" customisation. I'm thinking about JavaFX but I don't it yet,

  • what can I achieve with this technology ?
  • how hard is it ?
  • do you have examples of real-life examples of Swing/JavaFX integration ?

I would like to do something in this spirit of this, which is built on the .NET framework: GUI example with .NET techno

original link: http://www.patrickpayet.com/net/?p=329 edit: is their any getting started overview sample code that I can read to get a general feeling of the work needed to be done to achieve something in the spirit of the screenshot? maybe something like the miglayout's swing demo http://www.migcalendar.com/miglayout/swingdemoapp.jnlp

edit2: I found http://download.java.net/general/openjfx/demos/tutorial.jnlp it's really basic though, linked from http://www.deitel.com/ResourceCenters/Programming/JavaFX/JavaFXTutorialsandDemos/tabid/2187/Default.aspx

Yes, Swing is very customizable. I recommend reading Filthy Rich Clients.

For an example, have a look at Cezanne L&F.

Perhaps a philosophical question. I’ve seen some interesting visuals lately in GUIs, mostly on native platform APIs. I know that “it’s just software” and that likely, with enough work, anything can be done with pixels. The question is (finally!), is Java really an option for doing fancy things with a GUI. Seems like a silly thing I guess, but I kind of like some of the Windows Presentation Foundation work. I don’t see a consolidated effort like this for Java. Where should I look?

There has been some advancements in the GUI front in Java.

For example, beginning from Java 6 Update 10, it is possible to make transparent and shaped windows (i.e. arbitrarily-shaped windows commonly seen in media players) in Java:

How to Create Translucent and Shaped Windows

Filthy Rich Clients: Developing Animated and Graphical Effects for Desktop Java Applications by Chet Haase and Romain Guy is a good book full of tips on making advanced GUIs in Swing.

I have an application that gets a random image from a website. I have a JFrame with a JPanel in it. The image is added into a JLabel. My problem is that the new image won´t show. After I choose the "New Image" option in the menu bar I want the old image to be replaced with the new one.

public class GUI extends JFrame implements ActionListener {
    private JPanel imagePanel;
    private JScrollPane scroll;
    private JMenuBar menuBar;
    private JMenu menu;
    private JMenuItem menuItemNew;
    private JLabel label;


    public GUI(String title) throws MalformedURLException, IOException {
        super(title);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);        
        setLayout(new BorderLayout());            
        newImage();                 
        initComponents();             
        setSize(600, 400);     
        setLocationRelativeTo(null);
        initMenu();                   
        setVisible(true);
    }

    private void initComponents() {        
        scroll = new JScrollPane(imagePanel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);  
        add(scroll, BorderLayout.CENTER);              
    } 

    private void initMenu() {
        menuBar = new JMenuBar();
        menu = new JMenu("File");
        menuBar.add(menu);
        menuItemNew = new JMenuItem("New image");           
        menu.add(menuItemNew);              
        menuItemNew.addActionListener(this);
        setJMenuBar(menuBar);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
         if (e.getSource().equals(menuItemNew)) {
            newImage();                   
         }   
    }


    private void newImage() throws MalformedURLException, IOException {
        URL imageURL = new URL("http://xxxxxxx");
        BufferedImage buffImg = ImageIO.read(imageURL);
        ImageIcon icon = new ImageIcon(buffImg);
        label = new JLabel("", icon, JLabel.CENTER);
        label.setIcon(icon);
        imagePanel = new JPanel(new BorderLayout());
        imagePanel.add(label, BorderLayout.CENTER); 
        revalidate();    
        repaint();
    }
 }

The problem is that when you recreate your imagePanel, it never gets associated with the scroll pane.

The easiest way to fix this is to move the imagePanel and label creation up into initComponents, making label a field then in newImage()

private JLabel imageLabel;
private void newImage() throws MalformedURLException, IOException {
    ...
    imageLabel.setIcon(icon); 
    revalidate();    
    repaint();
} 

Also, as the next problem you will almost certainly have is that the random web images are not the right size, I highly recommend the image resizing utility methods provided by filthyrichclients.

I actually highly recommend the book as well, as it was one of the few books that actually demonstrated the power of Swing...

I'm trying to:

  1. display a text in a jLabel,
  2. wait for two seconds,
  3. then write a new text in the jLabel

this should be simple, but I get a strange bug: the first text is never written, the application just waits for 2 seconds and then displays the final text. here is the example code:


private void testButtonActionPerformed(java.awt.event.ActionEvent evt) {    
    displayLabel.setText("Clicked!");

    //  first method with System timer

    /*
    long t0=  System.currentTimeMillis();
    long t1=  System.currentTimeMillis();
            do{
                t1 = System.currentTimeMillis();
            }
            while ((t1 - t0) < (2000));
     */    

    // second method with thread.sleep()

    try {
        Thread.currentThread().sleep(2000);
    } catch (InterruptedException e) {}

    displayLabel.setText("STOP"); 
}

with this code, the text "Clicked!" is never displayed. I just get a 2 seconds - pause and then the "STOP" text. I tried to use System timer with a loop, or Thread.sleep(), but both methods give the same result.

You are messing with the event dispatcher thread. That will cause un-expected UI behavior as you are seeing. If you plan to do these type of animations, make sure to read up on what @Andrew Thompson suggested and also, see if you can read this - Filthy rich clients

Better to use a Swing Timer as shown in curde-example below:(yes, it is crude, I did not worry about stopping the timer etc):

public class DelayTest  extends JPanel{
    JLabel messageLabel = new JLabel();
    JButton actionButton = new JButton("Click Me");
    String[] messages = {"Clicked", "Stop!"};
    int i=0;
    public DelayTest(){
        super();
        add(messageLabel);
        add(actionButton);
        actionButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                Timer timer = new Timer(1000, new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent arg0) {
                        if(i<=1)
                            messageLabel.setText(messages[i++]);
                    }
                });
                timer.start();

            }

        });
    }

}

Edit
Why not stop the Timer:

           @Override
           public void actionPerformed(ActionEvent evt) {
              if (i <= 1) {
                 messageLabel.setText(messages[i++]);
              } else {
                 ((Timer)evt.getSource()).stop();
              }
           }
        });

I'm writing a little genetic algorithm in Java, as a school assignment. Up until now I've pretty much stuck to doing console applications. However I think a UI would be really helpful for this program, so I'd like to make one. I'm having trouble figuring out how to reconcile a GUI which is event-driven, and a console application which has a beginning and end.

Ideally I'd like to have a bunch of text boxes for settings, and then a Start button. Once you hit Start, the algorithm would start running and the GUI would update on a set interval with the latest program state. How the heck do I accomplish this without the algorithm freezing the GUI or vice-versa? I don't want either one waiting on the other.

How do I get my main loop to not freeze the GUI while the algorithm is running? I assume they need to be in separate threads, but I've never messed with threads before. That seems too complex for this task, which must be commonplace.

Sorry - it would seem like background tasks would be an easy and obvious sort of thing. Unfortunately, the Java Swing GUI threading model is a bit complicated. There have been some improvements in this area, but one still has to have some knowledge of threading first.

If you have time, I'd suggest reading the chapter on threading in Filthy Rich Clients - Painless Threading through SwingWorker.

alt text

If your impatient, just read the JavaDoc on SwingWorker. If you're really impatient, just copy the meaning of life example from the JavaDoc sample usage.

I would like to display an image in an area in my Jframe but the image takes up much space.

I would like to take it fair precise dimensions. How can I do this in Java

This is my simple code :

I am open to any proposal if I did not use the right method or the right class to instantiate the image.

import java.awt.*;
import javax.swing.*;

public class ExempleDeplace extends JFrame{

    private JLabel myLabel;

    public ExempleDeplace(){
         setLayout(new FlowLayout());
         setTitle("Fenetre, modele Duchi");
         setSize(500,700);
         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         JLabel j = new JLabel(new ImageIcon("src/images/bateau.png"));
         add(j);
         setVisible(true);
    }

    public static void main (String[] args) {    
          ExempleDeplace c = new ExempleDeplace();
    }
}

It's probably cleaner to just resize the image. I highly recommend the image resizing utility methods provided by filthyrichclients.

I actually highly recommend the book as well, as it was one of the few books that actually demonstrated the power of Swing...

Once you have the code, you will want to call

createCompatibleImage(myImage, myWidth,myHeight);