jjzjj

java - 单击边框时 JComboBox 弹出窗口立即出现和隐藏(糟糕的用户体验)

coder 2024-03-13 原文

当您有一个 swing JComboBox 并单击其边框时,弹出窗口会立即出现并消失。当我说单击时,我的意思是按下鼠标左键并立即松开。

这可能被认为是糟糕的用户体验,因为没有用户会期望它发生。单击组合框的边框时,任何用户都会期望以下行为之一:

  1. 要打开并保持打开状态的弹出窗口,
  2. 或者根本不打开。

肯定没有用户会期望弹出窗口立即打开和关闭。

用户不是故意点击边框的。但是当组合框很小并且他试图快速点击它时,它可能会经常发生。

在 2000 年,有人将此行为注册为 openjdk 站点中的错误:https://bugs.openjdk.java.net/browse/JDK-4346918

他们已将其识别为一个错误,但通过以下解决方案将其关闭:“不会修复”,观察如下:

I've been able to reproduce the problem but it's not significant so I'm not going to fix it. The problem is that the drop down portion of the combo box will hide when the mouse is released after clicking on the border. This bug doesn't have a very major impact.

我同意他们的观点,它并没有产生非常大的影响。但我仍然认为这会导致糟糕的用户体验,我想知道是否有一种简单的解决方法可以使弹出窗口在用户单击其边框时保持打开状态或根本不打开。

可以通过在任何 JComboBox 的边框上单击鼠标左键来重现所描述的行为。请参阅下面可以复制的简单代码:

import java.awt.FlowLayout;
import javax.swing.*;

public class JComboBoxUX{
    public static void main(String[] args){
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run(){
                JComboBox<String> combobox = new JComboBox<String>(
                        new String[]{"aaaaaaaaaa","bbbbbbbb","ccccccccc"});

                JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10));
                panel.add(combobox);

                JFrame frame = new JFrame("JComboBox UX");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setContentPane(panel);
                frame.setSize(300, 150);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

最佳答案

问题似乎出在:

class BasicComboPopup extends ... {

    private Handler getHandler() {
        if (handler == null) {
            handler = new Handler();
        }
        return handler;
    }

    private class Handler implements ... MouseListener ... {

        public void mouseReleased(MouseEvent e) {
            //...
            Component source = (Component)e.getSource();
            Dimension size = source.getSize();
            Rectangle bounds = new Rectangle( 0, 0, size.width - 1, size.height - 1 );
            if ( !bounds.contains( e.getPoint() ) ) {
                //...
                comboBox.setPopupVisible(false);
            }
        }
    }
}

通过从 size.widthsize.height 中减一,鼠标落在箭头按钮的边界之外,弹出菜单被隐藏。

解决这个问题是有问题的。 Handler 类是private,所以我们不能扩展它,getHandler()private,所以我们也不能在 BasicComboPopup 中覆盖它。

可以扩展 MetalComboBoxUI 并覆盖 createPopup() 以返回自定义 ComboPopup,例如扩展 BasicComboPopup > 但扩展 createMouseListener() 以返回与上面的 Handler 类似的类,但没有减法。

哦,对您希望支持的每个 LAF 执行相同的操作。嗯。

从另一个方向解决问题,可以扩展 MetalComboBoxButton(由 e.getSource() 返回)并覆盖 getSize() 方法在显示菜单时返回在两个方向上大一个像素的尺寸。当然,您仍然需要扩展和覆盖 MetalComboBoxUI 来创建和安装这个自定义按钮。

同样,您需要为您希望支持的每个 LAF 执行相同的操作。再次,yuk。

不幸的是,Swing 似乎没有所需的钩子(Hook)来轻松覆盖所需的功能,并且已将各种类标记为私有(private)内部实现细节,以防止它们被重用(以防止以后如果他们想要更改内部结构而损坏).

关于java - 单击边框时 JComboBox 弹出窗口立即出现和隐藏(糟糕的用户体验),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41062918/

有关java - 单击边框时 JComboBox 弹出窗口立即出现和隐藏(糟糕的用户体验)的更多相关文章

  1. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  2. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  3. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  4. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  5. ruby-on-rails - 简单的 Ruby on Rails 问题——如何将评论附加到用户和文章? - 2

    我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。

  6. ruby - RVM "ERROR: Unable to checkout branch ."单用户 - 2

    我在新的Debian6VirtualBoxVM上安装RVM时遇到问题。我已经安装了所有需要的包并使用下载了安装脚本(curl-shttps://rvm.beginrescueend.com/install/rvm)>rvm,但以单个用户身份运行时bashrvm我收到以下错误消息:ERROR:Unabletocheckoutbranch.安装在这里停止,并且(据我所知)没有安装RVM的任何文件。如果我以root身份运行脚本(对于多用户安装),我会收到另一条消息:Successfullycheckedoutbranch''安装程序继续并指示成功,但未添加.rvm目录,甚至在修改我的.bas

  7. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  8. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  9. Observability:从零开始创建 Java 微服务并监控它 (二) - 2

    这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/

  10. 【Java 面试合集】HashMap中为什么引入红黑树,而不是AVL树呢 - 2

    HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候

随机推荐