У меня есть фрейм, в котором есть пара JEditorPanes
компонентов. Один из них редактируемый, и пользователи могут ввести его. DocumentListener
, прикрепленный к этой панели редактора, синхронизирует содержимое этого с другим при изменении текста. Это, казалось, работало хорошо.
Затем я добавил ActionListener
, прикрепленный к кнопке для загрузки содержимого из файла. Я предполагал, что слушатель документа будет вызван этим обновлением текста и синхронизирует данные из панели редактора ввода, но, к сожалению, это только частично работает. Похоже, что не все содержимое, загруженное на панель ввода, загружается на панель вывода.
Я подозреваю, что существует некоторая гонка между слушателем действия, обновляющим панель ввода, и слушателем документа, читающим панель ввода и обновляющим панель вывода. Я не уверен, так ли это, и если да, то как это исправить.
public class EditorFrame extends JFrame {
private static final long serialVersionUID = 7119768788946124936L;
private JFrame _parentframe;
private JEditorPane _inputpane;
private JScrollPane _inputscrollpane;
private JButton _inputloadbutton;
private JPanel _inputbuttonpanel;
private JPanel _inputpanel;
private JEditorPane _outputpane;
private JScrollPane _outputscrollpane;
private JPanel _outputpanel;
private JPanel _editorpanel;
private JButton _savebutton;
private JButton _discardbutton;
private JPanel _buttonpanel;
private JPanel _contentpanel;
public EditorFrame(JFrame pframe) {
super("Editor");
this._parentframe = pframe;
this.init();
}
public EditorFrame(JFrame pframe) {
super("Editor");
this._parentframe = pframe;
this.init();
}
private boolean init() {
Dimension editorsize = new Dimension(750,500);
this._inputpane = new JEditorPane();
this._inputpane.setContentType("text/plain");
this._inputpane.setPreferredSize(editorsize);
this._inputpane.setBorder(BorderFactory.createLineBorder(Color.black));
this._inputpane.setEditable(true);
this._inputpane.setVisible(true);
this._inputscrollpane = new JScrollPane(this._inputpane, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
this._inputloadbutton = new JButton("Load Content");
EditorFrameLoadButtonActionListener loadbutton_actionlistener = new EditorFrameLoadButtonActionListener(this);
this._inputloadbutton.addActionListener(loadbutton_actionlistener);
this._inputbuttonpanel = new JPanel();
this._inputbuttonpanel.add(this._inputloadbutton);
this._inputpanel = new JPanel();
this._inputpanel.setLayout(new BoxLayout(this._inputpanel, BoxLayout.PAGE_AXIS));
this._inputpanel.add(this._inputscrollpane);
this._inputpanel.add(this._inputbuttonpanel);
this._outputpane = new JEditorPane();
this._outputpane.setContentType("text/html");
this._outputpane.setPreferredSize(editorsize);
this._outputpane.setBorder(BorderFactory.createLineBorder(Color.black));
this._outputpane.setEditable(false);
this._outputpane.setVisible(true);
HTMLEditorKit output_htmleditorkit = new HTMLEditorKit();
this._outputpane.setEditorKit(output_htmleditorkit);
this._outputscrollpane = new JScrollPane(this._outputpane, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
this._outputpanel = new JPanel();
this._outputpanel.add(this._outputscrollpane);
this._editorpanel = new JPanel();
this._editorpanel.add(this._inputpanel);
this._editorpanel.add(this._outputpanel);
this._savebutton = new JButton("Save");
this._savebutton.setEnabled(false);
this._discardbutton = new JButton("Discard");
CloseButtonActionListener discardbuttonlistener = new CloseButtonActionListener(this);
this._discardbutton.addActionListener(discardbuttonlistener);
this._buttonpanel = new JPanel();
this._buttonpanel.add(this._savebutton);
this._buttonpanel.add(this._discardbutton);
this._contentpanel = new JPanel();
this._contentpanel.setLayout(new BorderLayout());
this._contentpanel.add(this._titlepanel, BorderLayout.PAGE_START);
this._contentpanel.add(this._editorpanel, BorderLayout.CENTER);
this._contentpanel.add(this._buttonpanel, BorderLayout.PAGE_END);
this.setContentPane(this._contentpanel);
EditorFrameInputPaneDocumetListener doclistener = new EditorFrameInputPaneDocumetListener(this);
this._inputpane.getDocument().addDocumentListener(doclistener);
EditorFrameWindowListener windowlistener = new EditorFrameWindowListener(this._parentframe);
this.addWindowListener(windowlistener);
this.pack();
this.setVisible(true);
return true;
}
public void setInputPane(String instr) {
this._inputpane.setText(instr);
}
public void setOutputPane(String outstr) {
this._outputpane.setText(outstr);
}
public String getInputPane() {
return this._inputpane.getText();
}
public String getOutputPane() {
return this._outputpane.getText();
}
public void syncPanes() {
String data = this._inputpane.getText();
this._outputpane.setText(data);
}
public void enableSaveButton() {
this._savebutton.setEnabled(true);
}
}
public class EditorFrameInputPaneDocumetListener implements DocumentListener{
private EditorFrame _frame;
public EditorFrameInputPaneDocumetListener(EditorFrame f) {
this._frame = f;
}
@Override
public void changedUpdate(DocumentEvent arg0) {
this.synchAction();
}
@Override
public void insertUpdate(DocumentEvent arg0) {
this.synchAction();
}
@Override
public void removeUpdate(DocumentEvent arg0) {
this.synchAction();
}
private void synchAction() {
this._frame.syncPanes();
this._frame.enableSaveButton();
}
}
public class EditorFrameLoadButtonActionListener implements ActionListener{
private EditorFrame _frame;
public EditorFrameLoadButtonActionListener(EditorFrame frame) {
this._frame = frame;
}
@Override
public void actionPerformed(ActionEvent arg0) {
JFileChooser fc;
String path;
String ext;
fc = new JFileChooser();
fc.setAcceptAllFileFilterUsed(false);
if (fc.showOpenDialog(this._frame) == JFileChooser.APPROVE_OPTION) {
path = fc.getSelectedFile().getPath();
ext = AbsConverter.getExtension(path);
switch(ext) {
case "png" :
this.loadImage(path);
break;
default :
String msg = String.format("File *.%s cannot be loaded", ext);
JOptionPane.showMessageDialog(this._frame, msg, "Load Error", JOptionPane.ERROR_MESSAGE);
}
}
}
private void loadImage(String file) {
String imageStr;
String inputStr;
imageStr = AbsConverter.imageString(file);
if (imageStr.equals("")) {
String msg = String.format("Could not load image");
JOptionPane.showMessageDialog(this._frame, msg, "Load Error", JOptionPane.ERROR_MESSAGE);
}
else {
inputStr = "";
inputStr = inputStr + "<html>\n";
inputStr = inputStr + "<body>\n";
inputStr = inputStr + "<img src=\"";
inputStr = inputStr + imageStr;
inputStr = inputStr + "\" >\n";
inputStr = inputStr + "</body>\n";
inputStr = inputStr + "</html>\n";
this._frame.setInputPane(inputStr);
//this._frame.setOutputPane(inputStr);
}
}
}