Java Swing StyledDocument получить элемент дерева / SelectedText Стиль как жирный, курсив
Эй, у меня есть несколько вопросов / проблем.
Я должен создать небольшую программу для редактирования текста. (Выбранный) текст должен быть стиля. Полужирный, Курсив, Подчеркнутый, Выравнивание по центру вправо-влево. Работает отлично. Я использовал конкретные действия StyleEditorKit.
Моя проблема сейчас в том, что эти действия выполняются с помощью кнопок на панели jtoolbar и jmenuitems в jmenu / jmenubar.
Таким образом, есть два элемента щелчка, чтобы установить текст, выделенный жирным шрифтом, два элемента, чтобы установить текстовый курсив и так далее. Если щелкнуть один элемент (например, кнопку на панели инструментов), jmenuitem также должен быть выбран / активирован. Но как я могу это понять?
Моя идея - проверить выделенный текст (реализован CaretListener). Если текст выделен жирным шрифтом => установите кнопку и пункт меню активными. Но как я могу получить, если выбранный текст выделен жирным шрифтом / курсивом и т. Д.?
Я думаю, что есть дерево StyledDocument с листьями для этого материала. Но как я могу получить это дерево? как я могу получить листья?
Это мои первые шаги:
jTextPane1.addCaretListener(new CaretListener() {
@Override
public void caretUpdate(CaretEvent e) {
Highlight[] h = jTextPane1.getHighlighter().getHighlights();
for(int i = 0; i < h.length; i++) {
System.out.println(h[i].getStartOffset());
System.out.println(h[i].getEndOffset());
String selectedText = jTextPane1.getSelectedText();
StyledDocument styleddoc = (StyledDocument) jTextPane1.getDocument();
System.out.println(styleddoc);
}
}
});
Но я получаю только javax.swing.text.DefaultStyledDocument@5098cb76
Как я могу перебрать дерево и получить элементы leafs / bold или italic?
Спасибо
4 ответа
Сожалею. Это весь код:
Обновление 2: вот код
public class TestFrame extends javax.swing.JFrame {
/**
* Creates new form TestFrame
*/
public TestFrame() {
initComponents();
initButtons();
}
Action boldAction = new StyledEditorKit.BoldAction();
Action italicAction = new StyledEditorKit.ItalicAction();
Action underlineAction = new StyledEditorKit.UnderlineAction();
public void initButtons() {
JButton boldButton = new JButton(boldAction);
boldButton.setText("bold");
JButton italicButton = new JButton(italicAction);
boldButton.setText("italic");
JButton underlineButton = new JButton(underlineAction);
boldButton.setText("underline");
jToolBar1.add(boldButton);
jToolBar1.add(italicButton);
jToolBar1.add(underlineButton);
jTextPane1.addCaretListener(new CaretListener() {
@Override
public void caretUpdate(CaretEvent e) {
Highlighter.Highlight[] h = jTextPane1.getHighlighter().getHighlights();
for(int i = 0; i < h.length; i++) {
System.out.println("length " + h.length);
System.out.println(h[i].getStartOffset());
System.out.println(h[i].getEndOffset());
String selectedText = jTextPane1.getSelectedText();
StyledDocument styleddoc = (StyledDocument) jTextPane1.getDocument();
AttributeSet attributes = jTextPane1.getCharacterAttributes();
System.out.println("Bold " + attributes.containsAttribute(StyleConstants.Bold, Boolean.TRUE));
System.out.println("Italic " + attributes.containsAttribute("Italic " + StyleConstants.Italic, Boolean.TRUE));
System.out.println("Underline " + attributes.containsAttribute(StyleConstants.Underline, Boolean.TRUE));
}
}
});
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
jTextPane1 = new javax.swing.JTextPane();
jToolBar1 = new javax.swing.JToolBar();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jScrollPane1.setViewportView(jTextPane1);
jToolBar1.setRollover(true);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap(116, Short.MAX_VALUE)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 269, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(75, 75, 75))
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 192, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(23, 23, 23)
.addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(14, 14, 14)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 154, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(89, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(TestFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(TestFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(TestFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(TestFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new TestFrame().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTextPane jTextPane1;
private javax.swing.JToolBar jToolBar1;
// End of variables declaration
}
Мой код теперь выглядит так
public void jToolBarInitButtons() {
jTextPane1.addCaretListener(new CaretListener() {
@Override
public void caretUpdate(CaretEvent e) {
StyledDocument styleddoc = (StyledDocument) jTextPane1.getDocument();
AttributeSet attributes = jTextPane1.getCharacterAttributes();
System.out.println("bold " + attributes.containsAttribute(StyleConstants.Bold, Boolean.TRUE));
System.out.println("italic " + attributes.containsAttribute(StyleConstants.Italic, Boolean.TRUE));
}
Таким образом, есть два элемента щелчка, чтобы установить текст, выделенный жирным шрифтом, два элемента, чтобы установить текстовый курсив и так далее. Если щелкнуть один элемент (например, кнопку на панели инструментов), jmenuitem также должен быть выбран / активирован. Но как я могу это понять?
Создайте и пункт меню, и кнопку, передав одно и то же действие их конструкторам.
Похоже, вы намереваетесь показать жирный шрифт в кнопке и пункте меню, так что вы, вероятно, захотите создать JCheckBoxMenuItem и JToggleButton. Когда вы создаете Action, установите для его SELECTED_KEY ненулевое значение, чтобы кнопки обновляли его:
action.putValue(Action.SELECTED_KEY, false);
Из документации Акции:
SELECTED_KEY
Компоненты, учитывающие это свойство, используют значение только в том случае, если оно не
null
, Например, если вы установитеAction
который имеет нулевое значение дляSELECTED_KEY
наJToggleButton
,JToggleButton
не будет обновлять выбранное состояние в любом случае. Точно так же в любое времяJToggleButton
Изменения выбранного состояния изменят значение только наAction
еслиAction
имеет неnull
значение дляSELECTED_KEY
, Компоненты, которые поддерживают это свойство, поддерживают свое выбранное состояние в синхронизации с этим свойством. Когда то же самоеAction
используется с несколькими компонентами, все компоненты синхронизируют свое выбранное состояние с этим свойством.
Ваш CaretListener должен соответствовать описанию camickr.
Как я могу получить, если выбранный текст выделен жирным шрифтом / курсивом и т. д.?
В вашем CaretListener вы можете использовать:
AttributeSet attributes = jTextPane1.getCharacterAttributes();
System.out.println( attributes.containsAttribute(StyleConstants.Bold, Boolean.TRUE) );
Если щелкнуть один элемент (например, кнопку на панели инструментов), jmenuitem также должен быть выбран / активирован.
Вы должны использовать Action
:
Action bold = new StyledEditorKit.BoldAction();
JButton boldButton = new JButton( bold );
JCheckBoxMenuItem boldMenuItem = new JCheckBoxMenuItem( bold );
Когда вы устанавливаете состояние Action
состояние всех компонентов, использующих Action
изменено Например, вы можете сделать Action
выбран или включен.