4

在此处输入图像描述

这是我之前的问题的延续,我问如何在系统托盘中放置一些东西。
在社区的一些帮助下,我可以做到这一点。但是我无法做的是JTextField更改JWindow.

JWindow一个JPanel,一切都放在里面,JPanel包括Remind Mt At。但是,我无法在其中输入任何内容。 正确接收事件,因为它应该在鼠标进入时为白色,并在鼠标退出时返回默认颜色。 JTextFieldsetEditable(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();
        }
    }
//------------------------------------------------------------------------------
}

你还需要什么

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);
}
4

4 回答 4

6

规范说明isFocusableWindow()如下(我添加了编号以概述要点):

公共最终布尔值isFocusableWindow()

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

i)它的可聚焦窗口状态必须设置为真,

ii)必须在屏幕上显示其最近的所属框架或对话框,

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

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

如您所见,您的代码不符合第二条规则,因此您的代码JWindow不可聚焦。你需要在屏幕上有一个JDialogJFrame可见的,然后你可以用一个包裹它JWindow

new JWindow(frame);

或者您可以使用JDialogorJFrame直接代替JWindow. 如果您不想装饰窗户,只需调用Frame.setUndecorated(true)Dialog.setUndecorated(true)

于 2013-01-18T13:39:19.747 回答
2

像这样创建 JWindow

JWindow window = new JWindow(new JFrame(){public boolean isShowing(){return true;}});
于 2013-01-19T01:28:33.063 回答
1

我不是专家,但代码看起来不错。我唯一的建议是使用另一个类似于JTextField.

尝试使用 aJTextArea代替。其他组件,例如JTextFieldJTextPane也可以是选项。它们都存在于javax.swing库中,使用它import javax.swing.*

于 2013-01-18T07:51:46.703 回答
1

设置“setEditable(true)”是没有用的,因为在 JTextField 中默认 setEditable 为 true。“requestFocusInWindow()”在您的代码中做了什么。我怀疑那里的问题..不太确定...

于 2013-01-18T07:57:25.053 回答