4

UPDATE

This only happens when running on OS X. The issue isn't present on Windows. I'm using Eclipse Kepler and Oracle 1.7.0_45.jdk


The code below is a basic GUI running from an OSGI declarative services component. The problem is that when the GUI launches, I can't interact with the JTextField loginField. I can interact with the JButton loginButton. If I run the same code as a Java Application I can interact/edit the JTextField. So the issue must be due to it being launched as an OSGi bundle. Can anyone shed any light on what the issue might be?

DoctorDevice.java

package ie.ucd.sh.doctor;

import org.osgi.service.component.ComponentContext;
import ie.ucd.sh.db.context.DbContext;
import java.awt.EventQueue;

/**
 * This class runs the GUI for the Doctor Device.  It connects to the database using the abstraction
 * provided by the ie.ucd.sh.db.context bundle and displays information on the doctor that has logged in
 * into the device.
 * @author Conor Griffin
 */
public class DoctorDevice {

    protected DbContext dbContext;
    DoctorGUI window;

    public void activate(ComponentContext ctxt) {

        /**
         * Launch the swing GUI and set its DbContext
         */
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    window = new DoctorGUI();
                    window.frame.setVisible(true);
                    window.dbContext = dbContext;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    protected void deactivate(ComponentContext ctxt) {
        window.terminate();
    }

    public DbContext getContext() {
        return dbContext;
    }

    public void setContext(DbContext dbContext) {
        this.dbContext = dbContext;
        System.out.println("DbContext was set to " + dbContext);
    }

}

DoctorGUI.java

package ie.ucd.sh.doctor;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import java.awt.GridLayout;

import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

import ie.ucd.sh.db.context.DbContext;
import ie.ucd.sh.db.context.Doctor;
import ie.ucd.sh.db.context.Entity.Type;
import ie.ucd.sh.db.context.Nurse;
import ie.ucd.sh.db.context.Patient;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JTabbedPane;

public class DoctorGUI {

    protected JFrame frame;
    protected DbContext dbContext;
    private static DateFormat df = new SimpleDateFormat("HH:mm:ss");
    private Doctor currentUser;
    private JTextField loginField;

    /**
     * Create the application.
     */
    public DoctorGUI() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    public void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(new GridLayout(0, 2, 0, 0));

        JPanel inputPanel = new JPanel();
        frame.getContentPane().add(inputPanel);
        inputPanel.setLayout(null);

        JButton loginButton = new JButton("Login");
        loginButton.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                currentUser = login();
            }
        });
        loginButton.setBounds(137, 6, 82, 29);
        inputPanel.add(loginButton);

        loginField = new JTextField();
        loginField.setBounds(6, 5, 134, 28);
        inputPanel.add(loginField);
        loginField.setToolTipText("Enter your ID");
        loginField.setColumns(10);
        loginField.setEditable(true);

        JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
        frame.getContentPane().add(tabbedPane);
        loginField.requestFocusInWindow();
    }


    /**
     * Login the doctor
     * @return
     */
    private Doctor login() {
        int id = 0;
        Doctor doctor = null;
        try {
            id = Integer.parseInt(loginField.getText());
        } catch (NumberFormatException e) {
            e.printStackTrace();
            String title = "Invalid Value";
            String message = "ID must be numeric";
            JOptionPane.showMessageDialog(null, message, title, JOptionPane.ERROR_MESSAGE);
            return doctor;
        }

        doctor = (Doctor)dbContext.get(Type.Doctor, id);
        System.out.println(doctor.getFirstName() + " " + doctor.getLastName());

        return doctor;
    }

    /**
     * Set the JFrame to invisible and throw it away
     */
    public void terminate() {
        frame.setVisible(false);
        frame.dispose();
    }
}

DbContextClient.xml - The OSGi component definition

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.2.0" activate="activate" deactivate="deactivate" name="DbContextClient">
   <implementation class="ie.ucd.sh.doctor.DoctorDevice"/>
   <reference bind="setContext" cardinality="1..1" interface="ie.ucd.sh.db.context.DbContext" name="DbContext" policy="static" unbind="getContext"/>
</scr:component>
conorgriffin
  • 4,282
  • 7
  • 51
  • 88
  • 2
    Please post a [SSCCE](http://sscce.org): compilable, runnable and able to re-produce your issue for better help sooner- `sir Andrew Thompson` ;) – Sage Nov 22 '13 at 17:50
  • I've updated the example so it's clearer how to run it. It's an OSGi bundle using Declarative Services. When I launch the same code as a Java Application I can edit the `JTextField` no problem... – conorgriffin Nov 23 '13 at 08:25
  • can't guess what's happening, just a couple of unrelated comments: a) don't do any manual sizing/locating of components, ever - that's the exclusive responsibility of the LayoutManager b) don't use a lowlevel mouseListener for the button, an actionListener is what you want c) the aliased dbContext isn't kept in synch at all times (between doctorDevice and doctorGU). But as said, none of this would produce the mis-behaviour you describe ... – kleopatra Dec 05 '13 at 09:56

2 Answers2

2

After hours of researching this parameter added to run configuration parameters fixed my issue: -noSplash.

My eclipse settings:enter image description here

Dejan Pekter
  • 705
  • 3
  • 18
0

loginField.requestFocusInWindow();

Try requesting focus after the window is visible. (Call this method after you call setVisible(true) on the window which has this field.)

Pradhan
  • 518
  • 4
  • 14
  • I'll try it but do you see any reason why this would affect OS X and not Windows? – conorgriffin Dec 05 '13 at 08:57
  • I am not sure why this would behave differently.. My best guess would be the way it has been implemented in the OS. Every OS has its own way of handling UI events and there could be something wrong going on there. – Pradhan Dec 08 '13 at 03:49
  • My source of information... http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html ..._The component's window must be the current focused window. For this request to be granted a subclass of JComponent must be visible, enabled, and focusable, and have an input map for this request to be granted_... – Pradhan Dec 08 '13 at 03:56