Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jidesoft DocumentPane中的java.lang.IndexOutOfBoundsException:索引:1,大小:1_Java_Indexoutofboundsexception_Repaint_Jide_Repaintmanager - Fatal编程技术网

Jidesoft DocumentPane中的java.lang.IndexOutOfBoundsException:索引:1,大小:1

Jidesoft DocumentPane中的java.lang.IndexOutOfBoundsException:索引:1,大小:1,java,indexoutofboundsexception,repaint,jide,repaintmanager,Java,Indexoutofboundsexception,Repaint,Jide,Repaintmanager,Edit3:这个问题没有重复一般的“我的代码中有indexoutofboundsexception”问题,因为正如答案中明确指出的,这是一个广泛使用的第三方库jide common中的错误,经开发人员确认,下面有一个链接。这个bug最近被修复了(在这个问题发布之后),并且该库的许多旧版本仍然受到影响。因此,这些信息可能对其他开发人员有用,因为他们偶然发现jide common存在同样的问题 我在Java中面临GUI编程问题。我不确定问题的具体来源(仍然无法找到它)-可能是我的错误、jide组件中

Edit3:这个问题没有重复一般的“我的代码中有indexoutofboundsexception”问题,因为正如答案中明确指出的,这是一个广泛使用的第三方库
jide common
中的错误,经开发人员确认,下面有一个链接。这个bug最近被修复了(在这个问题发布之后),并且该库的许多旧版本仍然受到影响。因此,这些信息可能对其他开发人员有用,因为他们偶然发现jide common存在同样的问题

我在Java中面临GUI编程问题。我不确定问题的具体来源(仍然无法找到它)-可能是我的错误、jide组件中的错误代码,甚至是awt/swing focus或事件处理的错误

以下代码取决于

  • jidesoft:jide grids:3.5.1
  • com.jidesoft:jide组件:3.5.1
  • com.jidesoft:jide common:3.5.1
我在Stackoverflow上发现了,但在调试之后,我觉得CellEditor和其他组件的每一次修改都是在EDT中完成的

要重现错误,您应该运行此示例并打开包含CellEditor的选项卡(它必须是最后一行,否则不会发生索引溢出),然后在其中输入一些“不正确”的值,并且在不从编辑器中移除焦点的情况下,单击前面某个选项卡上的关闭“x”按钮。之后发生以下事件链:1)tab关闭/删除,2)CellEditor验证程序显示模式对话框,该对话框反过来触发tab窗格的重新绘制3)由于缺少(关闭)tab,引发ArrayIndexOutOfBounds异常

package com.example;

import com.jidesoft.document.DocumentComponent;
import com.jidesoft.document.DocumentPane;
import com.jidesoft.grid.JideTable;
import com.jidesoft.grid.TableModelWrapperUtils;
import com.jidesoft.grid.TextFieldCellEditor;
import com.jidesoft.swing.JideTabbedPane;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.math.BigDecimal;
import java.util.Random;

/**
 * Dependends on:
 * com.jidesoft:jide-grids:3.5.1
 * com.jidesoft:jide-components:3.5.1
 * com.jidesoft:jide-common:3.5.1
 */
public class ModalPopupFailure {

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setTitle("test");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        JComponent panel = new ModalPopupFailure().buildPanel();
        frame.setContentPane(panel);
        frame.setBounds(450, 300, 700, 500);
        frame.setVisible(true);
    }

    /**
     * @return table editor panel
     */
    private JPanel tableTab() {
        JPanel result = new JPanel(new BorderLayout());

        DefaultTableModel model = new DefaultTableModel(1, 1);
        model.setValueAt(new BigDecimal(0L), 0, 0);
        JideTable table = new JideTable(model);
        table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);

        final int actualCol0 = TableModelWrapperUtils.getActualColumnAt(table.getModel(), 0);
        CustomCellEditor bdce = new CustomCellEditor(Integer.class);
        table.getColumnModel().getColumn(actualCol0).setCellEditor(bdce);

        result.add(table, BorderLayout.CENTER);
        return result;
    }

    /**
     * @return Main panel with tabs
     */
    private JComponent buildPanel() {
        JPanel mainPanel = new JPanel(new BorderLayout());

        final DocumentPane documentPane = new DocumentPane();

        DocumentComponent dc1 = new DocumentComponent(new JLabel("tab1 label"), "aaa");
        documentPane.openDocument(dc1);

        DocumentComponent dc2 = new DocumentComponent(tableTab(), "TABLETAB");
        documentPane.openDocument(dc2);
        documentPane.setActiveDocument("TABLETAB");

        documentPane.setTabbedPaneCustomizer(new DocumentPane.TabbedPaneCustomizer() {
            @Override
            public void customize(final JideTabbedPane tabbedPane) {
                tabbedPane.setShowCloseButton(true);
                tabbedPane.setUseDefaultShowCloseButtonOnTab(false);
                tabbedPane.setShowCloseButtonOnTab(true);
            }
        });

        documentPane.setTabPlacement(SwingConstants.TOP);

        mainPanel.add(documentPane, BorderLayout.CENTER);
        mainPanel.add(new JButton(new AbstractAction("New tab") {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        Integer randInt = new Random().nextInt();
                        DocumentComponent newdc = new DocumentComponent(
                                new JLabel("Generated tab label " + randInt),
                                Integer.toString(randInt));

                        documentPane.openDocument(newdc);
                    }
                }),
                BorderLayout.NORTH);
        JLabel decription = new JLabel("<html>Steps to reproduce:<br />" +
                "TABLETAB should be the last tab<br />" +
                "The \"correct\" value for cell editor is 777.<br />" +
                "Enter any \"incorrect\" number, then close any tab standing before TABLETAB.<br />" +
                "An exception caused by window repaint should be raised by now.<br />" +
                "If dialog would not be modal, there would be no window repaint triggered.</html>");
        mainPanel.add(decription, BorderLayout.SOUTH);

        return mainPanel;
    }

    private class CustomCellEditor extends TextFieldCellEditor {

        boolean firstTime = true;

        public CustomCellEditor(Class<?> aClass) {
            super(aClass);
            _textField.setInputVerifier(new InputVerifier() {
                @Override
                public boolean verify(JComponent input) {
                    boolean valid = "777".equals(_textField.getText());
                    if (valid) return true;

                    final JDialog dialog = new JDialog();
                    dialog.setTitle("Exception expected");
                    dialog.setContentPane(new JLabel("<html>If one of previous tabs was closed, an exception should be raised by now.</html>"));
                    dialog.setLocationRelativeTo(null);

                    dialog.setModal(true); // Switching to false seems to fix the problem

                    dialog.setSize(new Dimension(300, 100));
                    dialog.setVisible(true);

                    return true;
                }
            });
        }

        @Override
        public boolean stopCellEditing() {
            System.out.println("Stopping cell edit " + new Random().nextInt() + "in edt: " + SwingUtilities.isEventDispatchThread());
            if (firstTime) {
                firstTime = false;
                return false;
            }

            return _textField.getInputVerifier().shouldYieldFocus(_textField) && super.stopCellEditing();
        }
    }
}
这是一个添加了一些调试信息的程序。 我仍然无法找出问题的根源,更不用说修复了。提前谢谢

编辑:好的,我现在知道的一件事是在verify()方法中显示一个对话框:

verify方法的存在只是为了确定输入是否有效,它不应弹出对话框或引起任何其他副作用。shouldYieldFocus方法调用verify,如果值无效,则将其设置为最小值或最大值。应力聚焦法允许产生副作用

因此,我将所有未实际验证的代码移到shouldYieldFocus()。这并没有解决问题,但进一步延迟了带有SwingUtilities.invokeLater()的dialog.show(),似乎工作正常,没有陷阱。。。然而

public CustomCellEditor(Class<?> aClass) {
    super(aClass);
    _textField.setInputVerifier(new InputVerifier() {

        @Override
        public boolean shouldYieldFocus(JComponent input) {
            boolean inputOK = verify(input);
            if (!inputOK) {
                final ru.esc.erp.core.components.Dialog dialog = new ru.esc.erp.core.components.Dialog();
                dialog.setTitle("Exception may be raised");
                dialog.setContentPane(new JLabel("<html>Modal dialog opened with yet another delay.</html>"));
                dialog.setLocationRelativeTo(null);

                dialog.setModal(true); // false "fixes" the problem

                dialog.setSize(new Dimension(300, 100));
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        dialog.setVisible(true);
                    }
                });
            }
            return inputOK;
        }

        @Override
        public boolean verify(JComponent input) {
            return "777".equals(_textField.getText());
        }
    });
}
公共CustomCellEditor(类aClass){
超级(aClass);
_setInputVerifier(新的InputVerifier(){
@凌驾
公共布尔值shouldYieldFocus(JComponent输入){
布尔输入=验证(输入);
如果(!inputOK){
final ru.esc.erp.core.components.Dialog=new ru.esc.erp.core.components.Dialog();
对话框.setTitle(“可能引发异常”);
setContentPane(新的JLabel(“模式对话框再次延迟打开”);
对话框.setLocationRelativeTo(空);
dialog.setModal(true);//false“修复”问题
设置尺寸(新尺寸(300100));
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
对话框.setVisible(true);
}
});
}
返回inputOK;
}
@凌驾
公共布尔验证(JComponent输入){
返回“777”。等于(_textField.getText());
}
});
}
编辑2:

好的,那是在吉德塔贝德帕内伊。 我已经用我的示例测试了修补过的jide oss,没有任何例外(不过,现在在关闭选项卡时出现了一些非关键的UI故障)。 找到了问题的根源

编辑:他们后来在3.6.17中修复了此错误:

由JIDE Support提供»2017年2月1日星期三上午12:10 正如你所知,这个bug在刚刚发布的3.6.17中被修复

我更进一步。不再使用DocumentPane、表和单元格编辑器。在JideTabbedPane上只有一个简单的文本字段(如果验证失败,它会显示一个模式对话框)。现在只使用oss库,所以任何人都可以运行这个示例。但是jide-oss-3.5.1的bug仍然存在。jide-oss-3.6.16也是如此。
public CustomCellEditor(Class<?> aClass) {
    super(aClass);
    _textField.setInputVerifier(new InputVerifier() {

        @Override
        public boolean shouldYieldFocus(JComponent input) {
            boolean inputOK = verify(input);
            if (!inputOK) {
                final ru.esc.erp.core.components.Dialog dialog = new ru.esc.erp.core.components.Dialog();
                dialog.setTitle("Exception may be raised");
                dialog.setContentPane(new JLabel("<html>Modal dialog opened with yet another delay.</html>"));
                dialog.setLocationRelativeTo(null);

                dialog.setModal(true); // false "fixes" the problem

                dialog.setSize(new Dimension(300, 100));
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        dialog.setVisible(true);
                    }
                });
            }
            return inputOK;
        }

        @Override
        public boolean verify(JComponent input) {
            return "777".equals(_textField.getText());
        }
    });
}