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

时间:2013-01-18 07:37:23

标签: java swing jtextfield jwindow

enter image description here

这是我上一个问题的继续,我问过如何在系统托盘中放置东西 在社区的一些帮助下,我可以做到这一点。但是,我无法更改JTextFieldJWindow的文字。

JWindow有一个JPanel,所有内容都放在JPanel内,包括{strong>提醒Mt At 的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();
        }
    }
//------------------------------------------------------------------------------
}

你还需要什么

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 个答案:

答案 0 :(得分:6)

specificationisFocusableWindow()如下(我添加了编号来概述要点):

  

public final boolean isFocusableWindow()

     

返回此Window是否可以成为焦点窗口,即   此窗口或其任何子组件是否可以成为焦点   所有者。对于可聚焦的框架或对话框,其可聚焦窗口   state必须设置为true。 对于不是框架或窗口的窗口   对话可以集中精力,

     

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

     

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

     

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

     

如果不满足任何这些条件,则不会   此窗口及其任何子组件都可以成为焦点所有者。

正如您所看到的,您的代码不符合第二条规则,因此您的JWindow无法集中精力。您需要在屏幕上显示JDialogJFrame,然后您可以使用JWindow包装它:

new JWindow(frame);

或者您可以直接使用JDialogJFrame代替JWindow。如果您不希望装饰窗口,请拨打Frame.setUndecorated(true)Dialog.setUndecorated(true)

答案 1 :(得分:2)

像这样创建JWindow

JWindow window = new JWindow(new JFrame(){public boolean isShowing(){return true;}});

答案 2 :(得分:1)

我不是专家,但代码看起来不错。我唯一的建议是使用与JTextField类似的其他组件。

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

答案 3 :(得分:1)

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