我正在製作觸摸屏鍵盤。當我按下shift鍵時(從小寫字母到大寫字母),我希望字母鍵改變文字。這是我目前執行的一個片段:批量重繪使用FormLayout的擺動組件
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字符串字段。
這裏的問題是按鈕以混沌的方式更新。我明白爲什麼會這樣;當我調用setText()時,它將調用repaint()以獲取單個組件,並且每個按鈕都會發生這種情況。我的問題是,我能夠「批量重繪」這些按鈕,而不會破壞Swing的設計(我不希望覆蓋AbstractButton的setText()方法)。謝謝。
UPDATE
原來這是一個的FormLayout問題。下面是說明問題的簡單代碼(請注意,您需要JGoodies表單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保存。無論如何,即使它被保留下來,呆滯的控件也同混沌更新控件一樣糟糕。猜猜我必須嘗試優化我們的繪圖代碼。感謝您的支持。
我要說的是,你正在做的事情錯了,但由於你忽略了提供一個[可運行示例](https://stackoverflow.com/help/mcve),它可以向你展示r問題,我們會建議的任何東西都會是瘋狂的猜測...... – MadProgrammer 2014-12-04 20:54:52
我不是要求你修復我的代碼。我在說,不管實現的細節如何,這就是Swing正在做的事情(在每個setText()調用中調用repaint()),並且我想阻止它執行它。我的問題是,是否有一個乾淨的方式來防止擺動對這些重新打電話行事。如果你堅持要看演示,我會盡快把一些東西放在一起。 – Ironcache 2014-12-04 21:03:48
@Ironcache實際上,repaint()是一個「延遲/合併」的方法,所以這意味着實際的繪畫只會在循環完成後發生,並且由循環觸發的所有重繪調用將合併爲一個重繪。所以這個問題很難被你的解釋所引起。請提供[mcve](https://stackoverflow.com/help/mcve) – 2014-12-04 21:08:37