Jar Bundler Using Osxadapter Causing Application to Lag or Terminate

JAR Bundler using OSXAdapter causing application to lag or terminate

After doing it, I'm not fully convinced a SwingWorker is a simpler (aka: better) solution - still requires additional thread synching (between the worker thread and the "outer" thread which passes in the file/names). Anyway (taking the opportunity to learn, and be it by errors :), below is a crude proof of concept example for the basic idea:

  • implement the Controller as SwingWorker, which funnels the input from the outer thread into the EDT
  • make it accept input (from the adapter, f.i.) via a method doWork(..) which queues the input for publishing
  • implement doInBackground to succesively publish the input

open issues

  • synch the access to the local list (not an expert in concurrency, but pretty sure that needs to be done)
  • reliably detecting the end of the outer thread (here simply stops when the input queue is empty)

Feedback welcome :-)

public class GUI {
private JFrame frame = new JFrame();
private DefaultTableModel model = new DefaultTableModel();
private JTable table = new JTable(model);
private JScrollPane pane = new JScrollPane(table);

public GUI() {
model.addColumn("Name");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(pane);
frame.pack();
frame.setVisible(true);
}

public void addRow(String name) {
model.addRow(new Object[] { name });
}

/**
* Controller is a SwingWorker.
*/
public static class Controller extends SwingWorker<Void, String> {
private GUI gui;

private List<String> pending;

public Controller() {
gui = new GUI();
}

public void doWork(String newLine) {
if (pending == null) {
pending = new ArrayList<String>();
pending.add(newLine);
execute();
} else {
pending.add(newLine);
}
}

@Override
protected Void doInBackground() throws Exception {
while (pending.size() > 0) {
publish(pending.remove(0));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}

/**
* @inherited <p>
*/
@Override
protected void process(List<String> chunks) {
for (String object : chunks) {
gui.addRow(object);
}
}

}

/**
* Simulating the adapter.
*
* Obviously, the real-thingy wouldn't have a reference
* to the controller, but message the doWork refectively
*/
public static class Adapter implements Runnable {

Controller controller;

public Adapter(Controller controller) {
this.controller = controller;
}

@Override
public void run() {
for (int i=0; i<10; i++)
{
controller.doWork("Line "+(i+1));
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}
public static void main(String[] args)
{
System.err.println("Initializing controller");
new Adapter(new Controller()).run();
}

@SuppressWarnings("unused")
private static final Logger LOG = Logger.getLogger(GUI.class.getName());
}

How do I pass a file as argument to my Java application created using JAR Bundler?

I've used OSXAdapter for preferences, about, and quit functionality. You might be able to leverage it's introspective approach to avoid the restriction. As com.apple.eawt.ApplicationListener is deprecated, you might try com.apple.eawt.OpenFilesHandler instead.

JAR bundler not found in MAC PC after installing JDK

Solution:

The solution of this problem can be found in the following link. Apparently, Apple has discontinued the existence of JAR bundler.

AbstractTableModel updating from different threads

expect using SwingWorker.

I too would expect to use a SwingWorker, but you may have meant except SwingWorker.

The best practice is to update the TableModel on the event dispatch thread as shown here in the process() implementation of JDBCWorker, a subclass of SwingWorker.

Alternatively, you can update the table's model using EventQueue.invokeLater(), as shown here, but the approach is tedious and error prone. See the comments for details.

Interacting with JTable which is rapidly updated with new rows

I don't think inserting rows in a table changes the selection, so as long as you are updating the TableModel on the EDT, the selected row is still same when the user shows the popup and chooses and action from the popup.

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;

public class TestJTableInsert {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
final DefaultTableModel model = new DefaultTableModel(0, 1);
new Timer(500, new ActionListener() {
private final Random random = new Random();
private int data = 1;

@Override
public void actionPerformed(ActionEvent e) {
model.insertRow(random.nextInt(model.getRowCount() + 1),
new Object[] { data++ });
}
}).start();

final JTable table = new JTable(model);
JPopupMenu popup = new JPopupMenu();
popup.add(new AbstractAction("Which row is this?") {

@Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(table,
"This is row " + table.getValueAt(table.getSelectedRow(), 0));
}
});
table.setComponentPopupMenu(popup);
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}


Related Topics



Leave a reply



Submit