Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can not edit the text of a JTextField inside a JPanel within a JWindow

enter image description here

This is in continuation of my previous question where I asked how to place something in the system tray.
After some help from the community, I could do that. However what I am unable to do is to change the text of the JTextField in the JWindow.

The JWindow has a JPanel and everything is placed within the JPanel, including the JTextField of Remind Mt At. However I am unable to type anything in it even though setEditable(true).
The JTextField receives events properly as it is supposed to be white when the mouse enters and go back to default color when mouse exits.

Is there any workaround for this?


SSCCE

package demo;

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.InputStream;

import javax.imageio.ImageIO;
import javax.sound.sampled.*;
import javax.swing.*;
import javax.swing.border.BevelBorder;

import example.Kernel32;

public class SSCCE {
    JPopupMenu popup = new JPopupMenu();
    JMenuItem exit = new JMenuItem("Exit");

    JWindow window = new JWindow();
    JPanel panel = new JPanel();
    int remindMeAt = 55;
    Kernel32.SYSTEM_POWER_STATUS batteryStatus = new Kernel32.SYSTEM_POWER_STATUS();

    Clip buzzer;
    AudioInputStream in;

    JLabel ACLineStatus = new JLabel();
    JLabel batteryCharge = new JLabel();
    JTextField enterReminder = new JTextField(3);
    Color defaultColor;

    String onACPower;
    String charge;
    String status;

    boolean keepLooping = true;

    boolean doRemind = true;
    boolean isCharging;
    boolean aboveThreshold;
    boolean remindedOnce = false;
//------------------------------------------------------------------------------
    public static void main(String[] args) {
        new SSCCE();
    }
//------------------------------------------------------------------------------
    public SSCCE(){
        if(SystemTray.isSupported()){
            setupGUI();
        }
    }
//------------------------------------------------------------------------------
    public void setupGUI(){
        try{
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            InputStream in = BatteryBeeperSystemTray.class.
                    getResourceAsStream("/images/battery_smaller.png");
            TrayIcon t = new TrayIcon(ImageIO.read(in));
            t.setToolTip("BatteryBeeper");
            SystemTray.getSystemTray().add(t);

        }catch(Exception e){

        }

        panel.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        defaultColor = window.getBackground();

        Kernel32.INSTANCE.GetSystemPowerStatus(batteryStatus);
        onACPower = batteryStatus.getACLineStatusString();
        charge = batteryStatus.getBatteryLifePercent();

        if(onACPower.equalsIgnoreCase("offline")){
            onACPower = "Battery";
        }else{
            onACPower = "AC Power";
            charge = "---";
        }

        ACLineStatus.setText(onACPower);
        ACLineStatus.setPreferredSize(new Dimension(150,40));
        ACLineStatus.setBorder(BorderFactory.createTitledBorder("Operating On"));

        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridwidth = 7;
        gbc.gridheight = 1;
        gbc.fill = GridBagConstraints.BOTH;
        panel.add(ACLineStatus,gbc);

        batteryCharge.setText(charge);
        batteryCharge.setBorder(BorderFactory.createTitledBorder("Current " +
                "Charge"));
        gbc.gridy++;
        panel.add(batteryCharge,gbc);
        panel.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));


        gbc.gridy++;
        enterReminder.setEditable(true);
        enterReminder.requestFocusInWindow();
        enterReminder.setText(Integer.toString(remindMeAt));
        enterReminder.addMouseListener(new TextHandler());
        enterReminder.setBackground(window.getBackground());
        enterReminder.setBorder(BorderFactory.createTitledBorder("Remind Me" +
                " At"));
        panel.add(enterReminder,gbc);

        window.add(panel);
        window.pack();
        window.setLocationRelativeTo(null);
        window.setVisible(true);


    }
//------------------------------------------------------------------------------
    public void checkIfReminderChanged(){
        //TODO DEFINE
    }   

//------------------------------------------------------------------------------
    public class TextHandler extends MouseAdapter{
        @Override
        public void mouseEntered(MouseEvent e){
            enterReminder.setBackground(Color.WHITE);
        }
//------------------------------------------------------------------------------
        @Override
        public void mouseExited(MouseEvent e){
            enterReminder.setBackground(defaultColor);
            checkIfReminderChanged();
        }
    }
//------------------------------------------------------------------------------
}

What you also need

package example;

import com.sun.jna.Native;
import com.sun.jna.Structure;
import com.sun.jna.win32.StdCallLibrary;
import java.util.*;

public interface Kernel32 extends StdCallLibrary {

    public Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("Kernel32", Kernel32.class);

    /**
     * @see http://msdn2.microsoft.com/en-us/library/aa373232.aspx
     */
    public class SYSTEM_POWER_STATUS extends Structure {
        public byte ACLineStatus;
        public byte BatteryFlag;
        public byte BatteryLifePercent;
        public byte Reserved1;
        public int BatteryLifeTime;
        public int BatteryFullLifeTime;

        @Override
        protected List<String> getFieldOrder() {
            ArrayList<String> fields = new ArrayList<String>();
            fields.add("ACLineStatus");
            fields.add("BatteryFlag");
            fields.add("BatteryFullLifeTime");
            fields.add("BatteryLifePercent");
            fields.add("BatteryLifeTime");
            fields.add("Reserved1");
            return fields;
        }

        /**
         * The AC power status
         */
        public String getACLineStatusString() {
            switch (ACLineStatus) {
                case (0): return "Offline";
                case (1): return "Online";
                default: return "Unknown";
            }
        }

        /**
         * The battery charge status
         */
        public String getBatteryFlagString() {
            switch (BatteryFlag) {
                case (1): return "High, more than 66 percent";
                case (2): return "Low, less than 33 percent";
                case (4): return "Critical, less than five percent";
                case (8): return "Charging";
                case ((byte) 128): return "No system battery";
                default: return "Unknown";
            }
        }

        /**
         * The percentage of full battery charge remaining
         */
        public String getBatteryLifePercent() {
            return (BatteryLifePercent == (byte) 255) ? "Unknown" : BatteryLifePercent + "%";
        }

        /**
         * The number of seconds of battery life remaining
         */
        public String getBatteryLifeTime() {
            return (BatteryLifeTime == -1) ? "Unknown" : BatteryLifeTime + " seconds";
        }

        /**
         * The number of seconds of battery life when at full charge
         */
        public String getBatteryFullLifeTime() {
            return (BatteryFullLifeTime == -1) ? "Unknown" : BatteryFullLifeTime + " seconds";
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append("ACLineStatus: " + getACLineStatusString() + "\n");
            sb.append("Battery Flag: " + getBatteryFlagString() + "\n");
            sb.append("Battery Life: " + getBatteryLifePercent() + "\n");
            sb.append("Battery Left: " + getBatteryLifeTime() + "\n");
            sb.append("Battery Full: " + getBatteryFullLifeTime() + "\n");
            return sb.toString();
        }
    }

    public int GetSystemPowerStatus(SYSTEM_POWER_STATUS result);
}
like image 333
An SO User Avatar asked Dec 27 '22 11:12

An SO User


1 Answers

The specification says about isFocusableWindow() as below (I added the numbering to outline the points):

public final boolean isFocusableWindow()

Returns whether this Window can become the focused Window, that is, whether this Window or any of its subcomponents can become the focus owner. For a Frame or Dialog to be focusable, its focusable Window state must be set to true. For a Window which is not a Frame or Dialog to be focusable,

i) its focusable Window state must be set to true,

ii) its nearest owning Frame or Dialog must be showing on the screen,

iii) and it must contain at least one Component in its focus traversal cycle.

If any of these conditions is not met, then neither this Window nor any of its subcomponents can become the focus owner.

As you can see, your code doesn't meet the second rule, so your JWindow is not focusable. You need to have a JDialog or JFrame visible on the screen and then you can wrap it with a JWindow:

new JWindow(frame);

Or you may use JDialog or JFrame directly instead of JWindow. If you don't want the window to be decorated, just call Frame.setUndecorated(true) or Dialog.setUndecorated(true).

like image 80
shuangwhywhy Avatar answered Feb 01 '23 09:02

shuangwhywhy