- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在制作触摸屏键盘。我希望字母键在我按下 shift 时更改文本(从小写到大写)。这是我当前实现的一个片段:
public void updatedButtons()
{
switch( m_state )
{
case QWERTY:
for( KeyboardButton button : m_keyboardButtons )
{
button.setText( button.getQwertyText().toLowerCase() );
}
break;
case QWERTY_SHIFT:
for( KeyboardButton button : m_keyboardButtons )
{
button.setText( button.getQwertyText().toUpperCase() );
}
break;
}
}
其中 KeyboardButton 是 JButton 的简单扩展,带有 qwertyText String 字段。
这里的问题是按钮以困惑的方式更新。我明白为什么会这样;当我调用 setText() 时,它会为单个组件调用 repaint(),每个按钮都会发生这种情况。我的问题是,我是否能够在不破坏 Swing 设计的情况下“批量重绘”这些按钮(我不希望重写 AbstractButton 的 setText() 方法)。谢谢。
更新
原来是FormLayout的问题。下面是说明问题的简单代码(请注意,您将需要一个 JGoodies Form Jar,并且可能需要修改断点值)。
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
public class JButtonTest
{
public static List<JButton> buttons = new ArrayList<JButton>();
public static boolean isCaps = false;
public static JFrame frame;
public static void main(String[] args)
{
frame = new JFrame();
frame.setSize( 1000, 100 );
JPanel panel = new JPanel();
// Form with 11 83x83 pixel squares, with 5x83 pixel spaces.
panel.setLayout( new FormLayout("83px, 5px, 83px, 5px, 83px, 5px, 83px, 5px, "
+ "83px, 5px, 83px, 5px, 83px, 5px, 83px, 5px, 83px, 5px, 83px, 5px, 83px, 5px, 86px",
"83px"));
int i = 1;
for (char c = 'a'; c < 'l'; ++c)
{
JButton button = new ComplexButton( Character.toString(c) );
button.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
updateButtons();
}
});
panel.add( button, new CellConstraints().xywh( (i*2)-1, 1, 1, 1, CellConstraints.FILL, CellConstraints.FILL) );
buttons.add( button );
++i;
}
frame.setContentPane( panel );
frame.setVisible( true );
}
// Enable the commented-out lines in this method to allow concurrent updating.
public static void updateButtons()
{
for (JButton button : buttons)
{
if (!isCaps)
button.setText( button.getText().toUpperCase() );
else
button.setText( button.getText().toLowerCase() );
//RepaintManager.currentManager( button ).markCompletelyClean( button );
}
//frame.repaint();
isCaps = !isCaps;
}
protected static class ComplexButton extends JButton
{
public ComplexButton( String string )
{
super(string);
}
@Override
public void paint( Graphics g )
{
int breakpoint = 3000000;
super.paint( g );
// Simulate some complex operations.
for (int i = 0; i < breakpoint; ++i)
{
g.setColor( new Color( i%255, (2*i)%255, (3*i)%255 ));
}
}
}
}
请注意,如果您从 FormLayout 更改为 FlowLayout,它工作得非常好(尽管本质上很慢)。如果您删除注释掉的代码上的注释,它也能正常工作(感谢 MadProgrammer)。
另请注意,如果将 printlns 放在 updateButtons() 方法的开头和结尾,该方法将在按钮停止更新之前很久结束,并且按钮不会同步更新。这意味着重绘的合并性质在某种程度上不会与 FormLayout 一起保留。
无论如何,即使它被保留下来,缓慢的控制与困惑更新的控制一样糟糕。我想我将不得不尝试优化我们的绘画代码。感谢支持。
最佳答案
Swing 中的绘画由 RepaintManager
控制,它决定何时更新内容。 RepaintManager
经过优化以减少它安排的绘制事件的数量,以保持性能。
这意味着当它收到一堆重绘请求时,它会将它们合并为尽可能少的绘制事件。这意味着当您从一堆按钮的循环中调用 setText
时,RepaintManager
可能已将其减少到尽可能接近一个(取决于关于你正在更新的内容,可能会有更多,但很可能会少于循环的迭代次数)...
例如,它似乎对我有用......
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestKeyboard {
public static void main(String[] args) {
new TestKeyboard();
}
public TestKeyboard() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private List<JButton> buttons;
public TestPane() {
setFocusable(true);
setLayout(new GridLayout(0, 4));
buttons = new ArrayList<>(26);
for (int index = 0; index < 26; index++) {
JButton btn = createButton(index);
buttons.add(btn);
add(btn);
}
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SHIFT) {
for (JButton btn : buttons) {
String text = btn.getText().toUpperCase();
btn.setText(text);
}
revalidate();
repaint();
}
}
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SHIFT) {
for (JButton btn : buttons) {
String text = btn.getText().toLowerCase();
btn.setText(text);
}
revalidate();
repaint();
}
}
});
}
protected JButton createButton(int index) {
JButton btn = new JButton(Character.toString((char) ('a' + index)));
btn.setMargin(new Insets(4, 4, 4, 4));
btn.setFocusable(false);
btn.setFocusPainted(false);
return btn;
}
}
}
关于java - 使用 FormLayout 批量重绘 Swing 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27303748/
我认为这可能是两个独立的问题。在Qt4.8中,QFormLayout是 The QFormLayout class manages forms of input widgets and their a
如屏幕截图所示,我的第二个 textLabel 和 textField 被下推在我添加左侧的文本区域之后。 我想将第二个textLabel和textField保留在第一个textLabel和textF
有人可以向我解释一下 FormLayout 上的 FormData 是如何工作的吗?我试图了解 FormAttachment 构造函数及其参数(分子、偏移量、分母)。你什么时候只需要其中一个,其中两个
我正在尝试设置一个 FormLayout使用 Vaadin 14,无论我尝试什么,标签都会出现在表单字段下方。我希望它们出现在字段的左侧,但即使让它们出现在字段上方也是朝着正确方向迈出的一步。 我相信
我正在使用 vaadin 开发 Web 应用程序,目前正在尝试实现地址簿。我查看了 github 上的官方实现并尝试构建它。 我遇到的问题与联系表有关。我希望能够单击网格中的一行并打开包含信息的表单。
我正在为复合容器使用 FormLayout。当我添加两个子项 label 和 clientArea 时,clientArea 取决于标签 -clientArea 仅在我首先添加标签时出现。 在添加子项
我是 vaadin 7 的新手,在格式方面有一些问题。 我花了几个小时但没有运气。 我有: 我的垂直布局上有 2 个表单布局。 每个表单布局上有 2 个标签。 Better check the scr
有没有一种方法可以使用 JGoodies FormLayout 在设置组件后更改其对齐方式? 例如, CellConstraints cc = new CellCosntraints(); panel
大家好,女士们, 当我让 Eclipse WindowBuilder 创建一个带有 FormLayout 的 JPanel 时,我想让这个创建是动态的,因为我正在编写的程序需要这种方式以避免 1000
我有一个 JPanel,它在 JScrollPane 中使用 FormLayout。 由于某种原因,当内容太大时,JScrollPane 不会显示滚动条。 我是 Java 新手,所以我很可能错过了一些
我很困惑为什么 QPlainTextEdit 小部件在添加到 QFormLayout 时不会垂直调整大小。在下面的代码中,文本字段正确地水平缩放,但不垂直缩放。 任何人都可以解释这种行为并提供解决方案
我在挥杆方面遇到了问题,一整天都无法解决。如果有人在 JTextField 中输入内容,我想在 JWindow 中显示一个弹出窗口。但是,如果布局使用 JGoodies FormLayout 并在一行
我要指定尺寸为200dlu < preferred component size < 600dlu 这是一个基本的三列布局,中间的列有时会是空的,但其他时候可能会有很长的字符串(文件路径等)。 我目前
我有下面的代码,其中我有一个 JPanel 需要占用 JFrame 的所有空间,但在框架完成时停止。使用表单布局时它不会。请看下面的代码 import com.jgoodies.forms.debug
这是我的代码: Composite outer = new Composite(parent, SWT.BORDER); outer.setBackground(new Color(null,
看起来 JComboBox 是一个非常非常讨厌调整高度的 Java 组件...我尝试了无数 set[Preferred|Minimum|Maximum]Size() 的组合 和各种不同的布局管理器,直
当创建像 Combo 这样简单的东西时,为什么我应该使用 FormLayout 和 FormData 而不是设置边界? 最佳答案 使用布局可以更轻松地支持不同的操作系统、用户设置、分辨率。它还有助于更
我需要一个不带滚动条的不可编辑的自动换行文本标签/字段/区域,该标签/字段/区域将随其父级(不带滚动条)调整大小。它将用于显示各种大小的文本,但“总是”有足够的空间来显示全文。在极少数情况下,用户将窗
如何使用 FormLayout(参见 here)将 Button(垂直)放置在中心?使用: final Button button = new Button(shell, SWT.NONE); but
我正在制作触摸屏键盘。我希望字母键在我按下 shift 时更改文本(从小写到大写)。这是我当前实现的一个片段: public void updatedButtons() { switch( m
我是一名优秀的程序员,十分优秀!