无法在JWindow中的JPanel内编辑JTextField的文本

Lit*_*ild 4 java swing jtextfield jwindow

在此输入图像描述

这是我之前的问题的继续,我问如何在系统托盘中放置一些东西.
在社区的一些帮助下,我可以做到这一点.但是什么我不能做的是改变的文本JTextFieldJWindow.

JWindowJPanel,一切都置于内JPanel,包括JTextField提醒百万吨.但是,即使我无法输入任何内容setEditable(true).
JTextField,因为它应该是白色的,当鼠标进入和返回时鼠标退出到默认的颜色正确地接收事件.

这有什么解决方法吗?


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();
        }
    }
//------------------------------------------------------------------------------
}
Run Code Online (Sandbox Code Playgroud)

你还需要什么

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);
}
Run Code Online (Sandbox Code Playgroud)

shu*_*why 6

规范说,大约isFocusableWindow()如下(我加的编号来勾勒分):

public final boolean isFocusableWindow()

返回此Window是否可以成为焦点窗口,即此Window或其任何子组件是否可以成为焦点所有者.要使Frame或Dialog可聚焦,其可聚焦窗口状态必须设置为true.对于不是可聚焦的框架或对话框的窗口,

i)其可聚焦窗口状态必须设置为true,

ii)必须在屏幕上显示最近的拥有框架或对话框,

iii)并且它必须在其焦点遍历循环中包含至少一个组件.

如果不满足任何这些条件,则此Window及其任何子组件都不能成为焦点所有者.

如您所见,您的代码不符合第二条规则,因此您JWindow无法集中精力.您需要在屏幕上显示JDialogJFrame显示,然后您可以使用以下内容进行包装JWindow:

new JWindow(frame);
Run Code Online (Sandbox Code Playgroud)

或者您可以使用JDialogJFrame直接代替JWindow.如果你不想要装饰窗户,只需打电话Frame.setUndecorated(true)Dialog.setUndecorated(true).

  • +1用于挖掘doc _and_想出解决方案:-) (3认同)