0

I want to fool arround with Java and especially the Swing library. I am having difficulies getting the hang of it tho.

On press of a button I am adding a new JInternalPanel to my UI which inside the constructor makes a 3rd party API call. The InternalFrame is not showing up for the duration of the API call, so basically the UI freezes completely for a few seconds.

How can this be solved? Is there any recommended way to archieve that?

Here is my simple code

public MarketView(){
    setTitle(TITLE);
    setSize(DEFAULT_SIZE);
    setMaximizable(true);
    setClosable(true);
    setIconifiable(true);
    setLayout(new BorderLayout());

    //this line here is causing the gui to freeze for duration of the 3rd party API call.
    System.out.println(this.api.getRestClient().getAllAssets().toString());
    show();
}

Updated my code based on some recommendations, still not sure if this is the proper way. Looks pretty verbose and somehow unesthetic to me.

public MarketView(){
    setTitle(TITLE);
    setSize(DEFAULT_SIZE);
    setMaximizable(true);
    setClosable(true);
    setIconifiable(true);
    setLayout(new BorderLayout());

    //this line here is causing the gui to freeze for duration of the 3rd party API call.
    new SwingWorker() {
        APIManager api = APIManager.getInstance();
        @Override
        protected List<TickerStatistics> doInBackground() throws Exception {
            List<TickerStatistics> ticker = api.getRestClient().getAll24HrPriceStatistics();
            return ticker;
        }

        @Override
        protected void done() {
            try {
                List<TickerStatistics> ticker = (List<TickerStatistics>) get();
                System.out.println(ticker);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } catch (ExecutionException e) {
                throw new RuntimeException(e);
            }
            System.out.println("Done");
        }
    }.execute();
    show();
}
BitQueen
  • 585
  • 1
  • 6
  • 20
  • 2
    You should probably use a SwingWorker and you can use the doInBackground. – matt Jan 26 '23 at 22:11
  • Long-running tasks should be performed on a background thread rather than on the UI thread. See [*Lesson: Concurrency in Swing*](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/). – Basil Bourque Jan 26 '23 at 22:14
  • Swing is single threaded - you should call long running or block operations from within the context of the Event Dispatching Thread - see [Concurrency in Swing](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html) for more details. The most likely solution would be to use `SwingWorker` - see [Worker Threads and SwingWorker](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html) for more details – MadProgrammer Jan 26 '23 at 22:15
  • Are you sure you want to learn Swing? It's been obsolete for several years now. – Dawood ibn Kareem Jan 26 '23 at 22:17
  • Honestly the only reason I want to code in java swing is cause there is one library I need that has no nodejs port :D Electron isnt really a fast alternative for desktop ui either – BitQueen Jan 26 '23 at 22:21
  • Swing is not and hasn't been obsolete. – matt Jan 27 '23 at 08:58

0 Answers0