package open.dolphin.client; import java.util.ArrayList; import java.util.List; import javax.swing.text.*; import open.dolphin.infomodel.ModuleModel; import open.dolphin.project.Project; /** * KartePane の StyledDocument class。 * * @author Kazushi Minagawa, Digital Globe, Inc. */ public class KarteStyledDocument extends DefaultStyledDocument { // stampHolder Style private final String STAMP_STYLE = "stampHolder"; // schemaHolder private final String SCHEMA_STYLE = "schemaHolder"; // attachmentHolder private final String ATTACHMENT_STYLE = "attachmentHolder"; // KartePane private KartePane kartePane; /** Creates new TestDocument */ public KarteStyledDocument() { } public void setParent(KartePane kartePane) { this.kartePane = kartePane; } public void setLogicalStyle(String str) { Style style = this.getStyle(str); this.setLogicalStyle(this.getLength(), style); } public void clearLogicalStyle() { this.setLogicalStyle(this.getLength(), null); } public void makeParagraph() { try { insertString(getLength(), "\n", null); } catch (BadLocationException e) { e.printStackTrace(System.err); } } /** * Stamp を挿入する。 * @param sh 挿入するスタンプホルダ */ public void stamp(final StampHolder sh) { try { Style runStyle = this.getStyle(STAMP_STYLE); if (runStyle == null) { runStyle = addStyle(STAMP_STYLE, null); } StyleConstants.setComponent(runStyle, sh); // キャレット位置を取得する int start = kartePane.getTextPane().getCaretPosition(); // Stamp を挿入する if (Project.getBoolean("stampSpace") && getLength()>0) { // 長さ==0なら先頭spaceは不要 insertString(start, "\n", null); insertString(start+1, " ", runStyle); insertString(start+2, "\n", null); // 改行をつけないとテキスト入力制御がやりにくくなる sh.setEntry(createPosition(start+1), createPosition(start+2)); // スタンプの開始と終了位置を生成して保存する } else { insertString(start, " ", runStyle); insertString(start+1, "\n", null); // 改行をつけないとテキスト入力制御がやりにくくなる sh.setEntry(createPosition(start), createPosition(start+1)); // スタンプの開始と終了位置を生成して保存する } } catch(BadLocationException | NullPointerException be) { be.printStackTrace(System.err); } } /** * Stamp を挿入する。 * @param sh 挿入するスタンプホルダ */ public void flowStamp(final StampHolder sh) { try { Style runStyle = this.getStyle(STAMP_STYLE); if (runStyle == null) { runStyle = addStyle(STAMP_STYLE, null); } // このスタンプ用のスタイルを動的に生成する StyleConstants.setComponent(runStyle, sh); // キャレット位置を取得する //masuda^ EDTでなくてもいいように //int start = kartePane.getTextPane().getCaretPosition(); int start = this.getLength(); //masuda$ // Stamp を挿入する insertString(start, " ", runStyle); // スタンプの開始と終了位置を生成して保存する Position stPos = createPosition(start); Position endPos = createPosition(start+1); sh.setEntry(stPos, endPos); } catch(BadLocationException | NullPointerException be) { be.printStackTrace(System.err); } } /** * Stampを削除する。 * @param start 削除開始のオフセット位置 * @param len */ public void removeStamp(int start, int len) { try { //masuda^ Stamp/Schemaをremoveするときは直後の改行も削除する // Stamp は一文字で表されている //remove(start, 1); //s.oh^ 2013/11/26 スクロールバーのリセット //if (start < getLength() && "\n".equals(getText(start+1, 1))) { if (start < getLength() && "\n".equals(getText(start+1, 1)) && (start + 1) < getLength()) { //s.oh$ remove(start, 2); } else { remove(start, 1); } //masuda$ } catch(BadLocationException be) { be.printStackTrace(System.err); } } /** * Stampを指定されたポジションに挿入する。 * @param inPos 挿入ポジション * @param sh 挿入する StampHolder */ public void insertStamp(Position inPos, StampHolder sh) { try { Style runStyle = this.getStyle(STAMP_STYLE); if (runStyle == null) { runStyle = addStyle(STAMP_STYLE, null); } StyleConstants.setComponent(runStyle, sh); // 挿入位置 int start = inPos.getOffset(); insertString(start, " ", runStyle); sh.setEntry(createPosition(start), createPosition(start+1)); } catch(BadLocationException be) { be.printStackTrace(System.err); } } public void stampSchema(SchemaHolder sc) { try { Style runStyle = this.getStyle(SCHEMA_STYLE); if (runStyle == null) { runStyle = addStyle(SCHEMA_STYLE, null); } // このスタンプ用のスタイルを動的に生成する StyleConstants.setComponent(runStyle, sc); // Stamp同様 int start = kartePane.getTextPane().getCaretPosition(); insertString(start, " ", runStyle); insertString(start+1, "\n", null); sc.setEntry(createPosition(start), createPosition(start+1)); } catch(BadLocationException be) { be.printStackTrace(System.err); } } public void flowSchema(final SchemaHolder sh) { try { Style runStyle = this.getStyle(SCHEMA_STYLE); if (runStyle == null) { runStyle = addStyle(SCHEMA_STYLE, null); } // このスタンプ用のスタイルを動的に生成する StyleConstants.setComponent(runStyle, sh); // キャレット位置を取得する //masuda^ EDTでなくてもいいように //int start = kartePane.getTextPane().getCaretPosition(); int start = this.getLength(); //masuda$ // Stamp を挿入する insertString(start, " ", runStyle); // スタンプの開始と終了位置を生成して保存する sh.setEntry(createPosition(start), createPosition(start+1)); } catch(BadLocationException | NullPointerException be) { be.printStackTrace(System.err); } } public void stampAttachment(AttachmentHolder sc) { try { Style runStyle = this.getStyle(ATTACHMENT_STYLE); if (runStyle == null) { runStyle = addStyle(ATTACHMENT_STYLE, null); } // このスタンプ用のスタイルを動的に生成する StyleConstants.setComponent(runStyle, sc); // Stamp同様 int start = kartePane.getTextPane().getCaretPosition(); insertString(start, " ", runStyle); insertString(start+1, "\n", null); sc.setEntry(createPosition(start), createPosition(start+1)); } catch(BadLocationException be) { be.printStackTrace(System.err); } } public void flowAttachment(final AttachmentHolder sh) { try { Style runStyle = this.getStyle(ATTACHMENT_STYLE); if (runStyle == null) { runStyle = addStyle(ATTACHMENT_STYLE, null); } // このスタンプ用のスタイルを動的に生成する StyleConstants.setComponent(runStyle, sh); // キャレット位置を取得する int start = kartePane.getTextPane().getCaretPosition(); // Stamp を挿入する insertString(start, " ", runStyle); // スタンプの開始と終了位置を生成して保存する sh.setEntry(createPosition(start), createPosition(start+1)); } catch(BadLocationException | NullPointerException be) { be.printStackTrace(System.err); } } public void insertTextStamp(String text) { try { clearLogicalStyle(); setLogicalStyle("default"); // mac 2207-03-31 int pos = kartePane.getTextPane().getCaretPosition(); insertString(pos, text, null); } catch (BadLocationException e) { e.printStackTrace(System.err); } } public void insertFreeString(String text, AttributeSet a) { try { insertString(getLength(), text, a); } catch (BadLocationException e) { e.printStackTrace(System.err); } } //masuda^ KarteStyledDocument内のStampHolderを取得する。pns先生のコード public List<StampHolder> getStampHolders() { List<StampHolder> list = new ArrayList<>(); int length = getLength(); for (int i = 0; i < length; ++i) { StampHolder sh = (StampHolder) StyleConstants.getComponent(getCharacterElement(i).getAttributes()); if (sh != null) { list.add(sh); } } return list; } // StampHolder内のModuleModelだけ返す sh.getStamp().getModuleInfoBean().getEntity().equals(entity) public List<ModuleModel> getStamps() { List<ModuleModel> list = new ArrayList<>(); int length = getLength(); for (int i = 0; i < length; ++i) { StampHolder sh = (StampHolder) StyleConstants.getComponent(getCharacterElement(i).getAttributes()); if (sh != null) { list.add(sh.getStamp()); } } return list; } //minagawa^ LSC Test public List<ModuleModel> getStampsToMatch(String entity) { List<ModuleModel> list = new ArrayList(); int length = getLength(); for (int i = 0; i < length; ++i) { StampHolder sh = (StampHolder) StyleConstants.getComponent(getCharacterElement(i).getAttributes()); if (sh != null && sh.getStamp().getModuleInfoBean().getEntity().equals(entity)) { list.add(sh.getStamp()); } } return list; } public List<StampHolder> getStampHoldersToMatch(String entity) { List<StampHolder> list = new ArrayList(); int length = getLength(); for (int i = 0; i < length; ++i) { StampHolder sh = (StampHolder) StyleConstants.getComponent(getCharacterElement(i).getAttributes()); if (sh != null && sh.getStamp().getModuleInfoBean().getEntity().equals(entity)) { list.add(sh); } } return list; } //minagawa$ // StampHolder直後の改行がない場合は補う public void fixCrAfterStamp() { try { int i = 0; while (i < getLength()) { StampHolder sh = (StampHolder) StyleConstants.getComponent(getCharacterElement(i).getAttributes()); String strNext = getText(++i, 1); if (sh != null && !"\n".equals(strNext)) { insertString(i, "\n", null); } } } catch (BadLocationException ex) { ex.printStackTrace(System.err); } } // 文書末の余分な改行文字を削除する public void removeExtraCR() { int len = getLength(); try { int pos; // 改行文字以外が出てくるまで文書末からスキャン for (pos = len - 1; pos >= 0; --pos) { if (!"\n".equals(getText(pos, 1))) { break; } } // 一文字戻す ++pos; if (len - pos > 0) { remove(pos, len - pos); } } catch (Exception ex) { ex.printStackTrace(System.err); } } // 文頭に挿入する場合、現在の文頭がComponentHolderならばそのEntryを更新する。 // position=0は特殊で移動しても変わらないため、スタンプホルダの開始位置がずれてしまうことへの対応 11/06/07 @Override public void insertString(int offs, String str, AttributeSet a) throws BadLocationException { if (offs == 0) { ComponentHolder ch = (ComponentHolder) StyleConstants.getComponent(getCharacterElement(offs).getAttributes()); if (ch != null) { super.insertString(offs, str, a); int pos = offs + str.length(); ch.setEntry(createPosition(pos), createPosition(pos + 1)); return; } } super.insertString(offs, str, a); } // KartePaneを返す。SOA/PTransferHandlerでインポート先を、JTextPane->KarteStyledDocument->KartePaneとたぐることができる // JTextPane textPane.getClientProperty("kartePane")でもOK? public KartePane getKartePane() { return kartePane; } //masuda$ }