CKeyboardListener activates inconsistently

A CKeyboardListener is only activated if the CDockable to which it is attached gains focus by clicking on its title bar; and it is deactivated only if some other CDockable gains focus by clicking on its title bar.

I’ve attached a small program that demonstrates this bug.

Actual behavior:

  1. Run the program.
  2. Click the title bar of the “Terminal” dockable.
  3. Press some keys. Observe that events are printed to System.out.
  4. Click the title bar of the “Chat” dockable.
  5. Press some keys. Observe that nothing is printed.
  6. Repeat steps 2 & 3.
  7. Click the white panel of the “Chat” dockable.
  8. Press some keys. Observe that events are still printed to System.out.

Expected behavior:
8. Nothing should be printed; CKeyboardListener should be deactivated when “Chat” gains focus.

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.KeyEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import bibliothek.gui.dock.common.CControl;
import bibliothek.gui.dock.common.DefaultSingleCDockable;
import bibliothek.gui.dock.common.SingleCDockable;
import bibliothek.gui.dock.common.event.CKeyboardListener;
import bibliothek.gui.dock.common.intern.CDockable;

public class HelloCommon implements Runnable {
	
	@Override
	public void run() {
		JFrame frame = new JFrame("Hello Common");	
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		CControl control = new CControl(frame);
		frame.add(control.getContentArea());
		
		SingleCDockable term = createPanel("Terminal", Color.BLACK);
		term.addKeyboardListener(new CKeyboardListener() {

			@Override
			public boolean keyPressed(CDockable arg0, KeyEvent arg1) {
				System.out.println(arg1);
				return false;
			}

			@Override
			public boolean keyReleased(CDockable arg0, KeyEvent arg1) {
				// ignored
				return false;
			}

			@Override
			public boolean keyTyped(CDockable arg0, KeyEvent arg1) {
				// ignored
				return false;
			}
			
		});
		
		SingleCDockable chat = createPanel("Chat", Color.WHITE);

		control.addDockable(term);		
		control.addDockable(chat);
		
		chat.setVisible(true);
		term.setVisible(true);
		
		frame.pack();
		frame.setVisible(true);
	}
	
	private SingleCDockable createPanel(String title, Color color) {
		JPanel panel = new JPanel();
		panel.setBackground(color);
		panel.setPreferredSize(new Dimension(800, 300));
		return new DefaultSingleCDockable(title, title, panel);		
	}
	
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new HelloCommon());
	}

}

Forgot to mention the version: 1.1.2p8c

I’ve discovered a workaround: add a mouse listener to the child component and have it call requestFocusInWindow().


	private SingleCDockable createPanel(String title, Color color) {
		final JPanel panel = new JPanel();
		panel.setBackground(color);
		panel.setPreferredSize(new Dimension(800, 300));
		// workaround for focus bug in 1.1.2p8c
		panel.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				panel.requestFocusInWindow();
			}
		});
		return new DefaultSingleCDockable(title, title, panel);
	}

You are right, there is an inconsistency here. I’ve uploaded a new version to deal a bit with this issue (1.1.2p8d) - at least it will remove the focus from the old Dockable. It will also search more vigilant for a focusable Component.
But since there are no focusable Components on either Dockable, you will not receive KeyEvents when clicking on the black or white panel. To correct that, you will need to add at least one focusable Component to the Dockable (in your example you can also call “panel.setFocusable(true)”).

I tested 1.1.2p8d, and just realized that the problem is theme-specific. The focus now works as expected with the Smooth and Flat themes, but the problem still exists when using the Eclipse theme. (I removed the theme setting from my example program for the sake of brevity… I never suspected that it could matter.)

Hm, I did not test different themes. I’ll have a second look, but not today (but the next version should be ready next weekend).