我希望这不是太具体,但我无法理解递归方法的逻辑流程。
目标:创建一个书籍类型gui,它将显示文本,保持换行符,在2个JTextAreas之间使用自动换行和页面换行。我不想通过滚动窗格执行此操作,并希望使用按钮向左/右翻页来设置书本效果。
[伪]代码:将文本拉入并处理(等宽线拟合),将X行放入页面。如果存在上一页/下一页,则启用左/右按钮。在左侧显示x页面,在右侧显示x + 1页面。使用(leftPageCursor)来保存当前的左页。
为了做到这一点,我的想法是有一个递归显示方法,“显示/隐藏”左/右按钮,将文本放到JTextAreas,并添加按钮监听器代码。它适用于第一次单击右键,但后来变得非常混乱,并且(leftPageCursor)失去控制。我为任何人创建了以下SSCCEE以查看我的意思/逻辑。
我真的很感激任何帮助,我没有想法。我尝试了很多东西(e.consume)没有运气。
SSCCEE:(请原谅长度 - 我希望它在保持良好评论的同时运行)
public class ReadJIntLauncher extends JFrame {
private static final long serialVersionUID = 1L;
static JTextArea textAreaLeft, textAreaRight;
static JButton btnPageLeft, btnPageRight;
static int leftPageCursor = 0, readMessageId = 1;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ReadJIntLauncher frame = new ReadJIntLauncher();
frame.setVisible(true);
HashMap<String, String> messages = new HashMap<String, String>();
messages.put("read_paragraph_1_0", "PAGE 1: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor");
messages.put("read_paragraph_1_1", "incididunt ut labore etdolore magna aliqua. Ut enim ad minim veniam, quis nostrud");
messages.put("read_paragraph_1_2", "exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute");
messages.put("read_paragraph_1_3", "irure dolor in reprehenderit in voluptate velit esseees");
messages.put("read_paragraph_1_4", "PAGE 2: cillum dolore deserunt anim id est laborum anim id est laborum incididunt ut");
messages.put("read_paragraph_1_5", "labore incididunt ut labore etdolore magna aliqua. Ut enim ad minim veniam, quis");
messages.put("read_paragraph_1_6", "exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute");
messages.put("read_paragraph_1_7", "exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.");
messages.put("read_paragraph_1_8", "PAGE 3: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor");
messages.put("read_paragraph_1_9", "incididunt ut labore etdolore magna aliqua. Ut enim ad minim veniam, quis nostrud");
messages.put("read_paragraph_1_10", "exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute");
messages.put("read_paragraph_1_11", "irure dolor in reprehenderit in voluptate velit esseees");
messages.put("read_paragraph_1_12", "PAGE 4: cillum dolore deserunt anim id est laborum anim id est laborum incididunt ut");
messages.put("read_paragraph_1_13", "labore incididunt ut labore etdolore magna aliqua. Ut enim ad minim veniam, quis");
messages.put("read_paragraph_1_14", "exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute");
messages.put("read_paragraph_1_15", "exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.");
messages.put("read_paragraph_1_16", "PAGE 5: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor");
messages.put("read_paragraph_1_17", "incididunt ut labore etdolore magna aliqua. Ut enim ad minim veniam, quis nostrud");
messages.put("read_paragraph_1_18", "exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.");
final HashMap<Integer, String> readLines = new HashMap<Integer, String>();
int lineCount = 0;
String entireText = "";
//grab all of the messages into entireText
for (int i = 0; i < Integer.MAX_VALUE; i++){
if (messages.containsKey("read_paragraph_" + readMessageId + "_" + i)){
String read = messages.get("read_paragraph_" + readMessageId + "_" + i);
entireText += read + " |";
} else {
break;
}
}
//split the entire text by spaces
String[] readSplitSpaces = entireText.split("\\s");
//put words into readLines
String singleLine = "";
for (String s : readSplitSpaces){
s = s + " ";
int wordLength = s.length();
if (s.contains("|")){
String[] sSplitStrings = s.split("\\|");
singleLine += sSplitStrings[0];
readLines.put(lineCount, singleLine);
lineCount++;
singleLine = sSplitStrings[1];
} else {
if ((singleLine.length() + wordLength) <= 26){
singleLine += s;
} else {
readLines.put(lineCount, singleLine);
lineCount++;
singleLine = s;
}
}
}
//print out readLines
for (int i = 0; i < Integer.MAX_VALUE; i++){
if (readLines.containsKey(i)){
System.out.println("[" + i + "] : " + readLines.get(i));
} else { break; }
}
//put readLines into readPages
final HashMap<Integer, String> readPages = new HashMap<Integer, String>();
int totalPageCount = lineCount / 15;
if (lineCount % 15 != 0){ //round up for partial pages
totalPageCount++;
}
for (int i = 0; i < totalPageCount; i++){
String tmpPage = "";
for (int k = 0; k < 15; k++){
if (readLines.containsKey(k + (i * 15))){
tmpPage += readLines.get(k + (i * 15)) + "\r\n";
}
}
readPages.put(i, tmpPage); //i is pageCount
}
//print out readPages
for (int i = 0; i < Integer.MAX_VALUE; i++){
if (readPages.containsKey(i)){
System.out.println("[" + i + "] : " + readPages.get(i));
} else { break; }
}
displayReadPages(readPages);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public ReadJIntLauncher() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 600, 430);
JPanel jint = new JPanel();
jint.setBounds(100, 100, 534, 428);
jint.setLayout(null);
textAreaLeft = new JTextArea();
textAreaLeft.setFont(new Font("Monospaced", Font.PLAIN, 14));
textAreaLeft.setBounds(25, 37, 213, 297);
jint.add(textAreaLeft);
textAreaRight = new JTextArea();
textAreaRight.setFont(new Font("Monospaced", Font.PLAIN, 14));
textAreaRight.setBounds(261, 37, 213, 297);
jint.add(textAreaRight);
btnPageLeft = new JButton("left");
btnPageLeft.setBounds(10, 345, 89, 23);
jint.add(btnPageLeft);
btnPageRight = new JButton("right");
btnPageRight.setBounds(385, 345, 89, 23);
jint.add(btnPageRight);
getContentPane().add(jint);
}
public static void displayReadPages(final HashMap<Integer, String> readConvo){
System.out.println("\nonLeftPage: " + leftPageCursor);
//enable buttons if necessary
if (leftPageCursor != 0){
btnPageLeft.setEnabled(true);
} else {
btnPageLeft.setEnabled(false);
}
if (readConvo.containsKey(leftPageCursor + 2)){
btnPageRight.setEnabled(true);
} else {
btnPageRight.setEnabled(false);
}
//set left and right page(possibly)
textAreaLeft.setText(readConvo.get(leftPageCursor)); System.out.println(" left page: " + leftPageCursor);
if (readConvo.containsKey(leftPageCursor + 1)) {
textAreaRight.setText(readConvo.get(leftPageCursor + 1)); System.out.println(" right page: " + (leftPageCursor + 1));
} else {
textAreaRight.setText("");
}
btnPageLeft.addMouseListener(new MouseListener() {
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1){
leftPageCursor -= 2;
displayReadPages(readConvo);
}
}
});
btnPageRight.addMouseListener(new MouseListener() {
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1){
leftPageCursor += 2;
displayReadPages(readConvo);
}
}
});
}
}
答案 0 :(得分:0)
所以我想出了答案,并希望将此留在这里以防万一有人偶然发现并希望从我的错误中吸取教训。我将.addMouseListener代码移动到构造函数中,它修复了问题。我想这是注册每次点击另一个听众,而不是'覆盖'可以这么说。
我现在唯一的问题是我仍然可以点击“禁用”按钮。
这是解决方案......
来源:CodeRanch
ActionListener是一个更高级别的语义事件,就像这样 当您的按钮被禁用时,这是正确的,即它不能 触发。 MouseListener是一个较低的事件。它也是如此 设计的。仅仅因为你已经禁用了按钮并没有阻止 人们试图点击它,而MouseListener就是 乖乖地告诉你发生了一次点击。这是事实 disabled是按钮状态的一部分,但不影响 事件MouseListener正在陷阱。