首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用不同的API基于另一个API创建Swing组件

使用不同的API基于另一个API创建Swing组件
EN

Stack Overflow用户
提问于 2014-03-25 17:03:42
回答 3查看 210关注 0票数 1

我想在现有的JComponent基础上创建一个新的Swing,但是使用不同的API。换句话说,我不想扩展现有的组件,因为我不希望它是可访问的API。

这里有一个例子来说明我的需要:

JCheckBox的替换,它显示两个按钮的开/关。这可以基于预先配置的JCommandButtonStrip (一些信息这里),但公开完全相同的JCheckBox API。不得更改JCommandButtonStrip的配置。

解决这一问题的最佳办法是什么?

Clarifications:

正如有人指出的那样,我写的关于API的内容还不清楚。

当然,JComponent有许多公共字段和方法,每个子类都可以使用它们。然后,JComponent的每个子类都可以添加自己的公共字段和方法。例如,AbstractButton添加isSelected()方法,而JCommandButtonStrip添加getButtonCount()方法。

所以,我的意思是:我想创建一个新的JComponent子类MyJComponent,它基于一个现有的ExistingJComponent。我不希望ExistingJComponent的公共方法(除了JComponent的方法)被我的类MyJComponent公开。然后,我想向MyJComponent添加一些公共方法。

请注意,我并不是在寻找JCommandButtonStrip/JCheckBox示例的替代方案。我对解决这个问题的一般方法很感兴趣。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-03-25 17:05:58

您可以创建一个扩展JComponent的新类,然后在构造函数中插入一个复选框。

代码语言:javascript
运行
复制
public class MyCoolCheckbox extends JComponent{
    private JCheckBox checkbox;
    public MyCoolCheckbox(String label) {
        checkbox= new JCheckBox(label);
        this.setLayout(new BorderLayout());
        this.add(checkbox, BorderLayout.CENTER);
    }
}

这显然是不完整的,您可能需要将某些方法委托给孩子。可能会很乱。IDEs (如IntelliJ IDEA )将为您生成所有这些,如果您点击alt- if (默认情况下),然后委托,然后选择复选框成员并选择您想要委派的条目。例如:

代码语言:javascript
运行
复制
public void setForeground(Color fg) {
    checkbox.setForeground(fg);
}

public void setBackground(Color bg) {
    checkbox.setBackground(bg);
}
public Color getForeground() {
    return checkbox.getForeground();
}

public Color getBackground() {
    return checkbox.getBackground();
}

请记住,因为子代码位于Swing组件树中,其他代码可以访问这些子代码,即使它们被标记为私有。

代码语言:javascript
运行
复制
((JCheckBox)myCoolCheckbox.getComponents()[0]).setSelected(true);
票数 3
EN

Stack Overflow用户

发布于 2014-03-25 23:23:24

基于这张JCommandButtonStrip图片

我认为您正在寻找JToggleButton,就像@垃圾上帝建议的那样,但是考虑到当前对您的“问题”的描述,我不确定按钮组。如果您需要按钮组,那么使用它。

不管怎样,我的回答指向了这句话:

这可以基于预先配置的JCommandButtonStrip (这里有一些信息),但公开完全相同的JCheckBox API。

再一次,我们还不清楚你是在尝试做一个按钮条,比如JCommandButtonStrip,还是想做其他的事情。但是,您可以从JComponent扩展您自己的组件,并且只从外部委托那些需要的方法。例如,假设您想要做一个按钮条,比如JCommandButtonStrip。然后你就可以拥有:

  • 一个从JComponent扩展的类:按钮条。
  • 另一个提供API将“命令”添加到按钮栏中。

Note:已经有一个JToolBar组件可以完美地使用,而无需重新发明轮子。下面的示例只是为了向您展示您可以控制提供给开发人员的API。

MyCommandBar.java

代码语言:javascript
运行
复制
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;
import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.event.ChangeListener;

public class MyCommandBar extends JComponent {

    private final JPanel content;
    private final Map<String, CommandItem> map = new HashMap<>();

    public MyCommandBar() {
        super();
        content = new JPanel(new GridLayout(1, 0));
        content.setOpaque(false);
        setLayout(new FlowLayout());
        add(content);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics graphics = g.create();
        graphics.setColor(getBackground());
        graphics.fillRect(0, 0, getWidth(), getHeight());
        graphics.dispose();
    }

    public void addCommandItem(String actionCommand, CommandItem commandItem) {
        if(map.get(actionCommand) != null) {
            removeCommandItem(actionCommand);
        }
        content.add(commandItem.getComponent());
        map.put(actionCommand, commandItem);
    }

    public void removeCommandItem(String actionCommand) {
        CommandItem commandItem = map.get(actionCommand);
        if(commandItem != null) {
            content.remove(commandItem.getComponent());
            content.revalidate();
            content.repaint();
            map.remove(actionCommand);
        }
    }

    public CommandItem getCommandItem(String actionCommand) {
        return map.get(actionCommand);
    }

    public static class CommandItem {

        public static final int TOGGLE_BUTTON_STYLE = 0;
        public static final int CHECK_BOX_STYLE = 1;
        public static final int DEFAULT_BUTTON_STYLE = 2;

        private final AbstractButton component;

        public CommandItem(String text, boolean state, Icon icon, int style) {
            switch(style) {
                case TOGGLE_BUTTON_STYLE : component = new JToggleButton(text, icon, state); break;
                case CHECK_BOX_STYLE : component = new JCheckBox(text, icon, state); break;
                    default: component = new JButton(text, icon);
            }
        }

        protected AbstractButton getComponent() {
            return component;
        }

        public void addActionListener(ActionListener listener) {
            component.addActionListener(listener);
        }

        public void addChangeListener(ChangeListener listener) {
            component.addChangeListener(listener);
        }

        public void setAction(Action action) {
            component.setAction(action);
        }
    }
}

使用实例

这个代码片段展示了如何使用MyCommandBar类:

代码语言:javascript
运行
复制
MyCommandBar commandBar = new MyCommandBar();
commandBar.setBorder(BorderFactory.createLineBorder(Color.black, 1));
commandBar.addCommandItem("BOLD", new MyCommandBar.CommandItem("<html><b>Bold</b></html>", true, null, MyCommandBar.CommandItem.TOGGLE_BUTTON_STYLE));
commandBar.addCommandItem("ITALICS", new MyCommandBar.CommandItem("<html><i>Italics</i></html>", false, null, MyCommandBar.CommandItem.CHECK_BOX_STYLE));
commandBar.addCommandItem("UNDERLINE", new MyCommandBar.CommandItem("<html><u>Underline</u></html>", false, null, MyCommandBar.CommandItem.DEFAULT_BUTTON_STYLE));

你会看到这样的东西:

票数 1
EN

Stack Overflow用户

发布于 2014-03-26 19:52:50

可以使用引用JComponent转发类的私有字段创建JComponentJComponent子类。

ExistingComponent的交互是通过MyJComponent的方法与转发类完成的,您可以自由地向MyJComponent添加更多的方法。

关于转发类使用的委托模式,请参见有效的Java项目16。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22641561

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档