<version>1.101.104</version>
<scope>compile</scope>
</dependency>
-
+
+ <dependency>
+ <groupId>io.github.olyutorskii</groupId>
+ <artifactId>quetexj</artifactId>
+ <version>1.0.4</version>
+ <scope>compile</scope>
+ </dependency>
+
</dependencies>
<repositories/>
package jp.sfjp.jindolf.log;
+import io.github.olyutorskii.quetexj.MaxTracker;
+import io.github.olyutorskii.quetexj.MvcFacade;
import java.awt.Container;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
import java.util.logging.Handler;
+import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JSeparator;
* ログ表示ウィンドウ。
*/
@SuppressWarnings("serial")
-public class LogFrame extends JDialog {
+public final class LogFrame extends JDialog {
private static final String CMD_CLOSELOG = "CMD_CLOSE_LOG";
- private static final String CMD_CLEARLOG = "CMD_CLEAR_LOG";
- private final LogPanel logPanel = new LogPanel();
- private final JButton clearButton = new JButton("クリア");
- private final JButton closeButton = new JButton("閉じる");
+ private final MvcFacade facade;
+
+ private final LogPanel logPanel;
+ private final JButton clearButton;
+ private final JButton closeButton;
/**
* コンストラクタ。
+ *
* @param owner フレームオーナー
*/
public LogFrame(Frame owner){
super(owner);
+ this.facade = new MvcFacade();
+
+ this.logPanel = new LogPanel(this.facade);
+ this.clearButton = new JButton();
+ this.closeButton = new JButton();
+
design();
- this.clearButton.setActionCommand(CMD_CLEARLOG);
+ Action clearAction = this.facade.getClearAction();
+ this.clearButton.setAction(clearAction);
+ this.clearButton.setText("クリア");
+
this.closeButton.setActionCommand(CMD_CLOSELOG);
+ this.closeButton.addActionListener(event -> {
+ String cmd = event.getActionCommand();
+ if(CMD_CLOSELOG.equals(cmd)){
+ setVisible(false);
+ }
+ });
+ this.closeButton.setText("閉じる");
- ActionListener actionListener = new ActionWatcher();
- this.clearButton.addActionListener(actionListener);
- this.closeButton.addActionListener(actionListener);
+ MaxTracker tracker = this.facade.getMaxTracker();
+ tracker.setTrackingMode(true);
setResizable(true);
setLocationByPlatform(true);
return this.logPanel.getHandler();
}
- /**
- * ログ内容をクリアする。
- */
- public void clearLog(){
- this.logPanel.clearLog();
- return;
- }
-
-
- /**
- * ボタン操作を監視する。
- */
- private final class ActionWatcher implements ActionListener{
-
- /**
- * コンストラクタ。
- */
- ActionWatcher(){
- super();
- return;
- }
-
- /**
- * {@inheritDoc}
- * ボタン押下イベント処理。
- * @param event {@inheritDoc}
- */
- @Override
- public void actionPerformed(ActionEvent event){
- String cmd = event.getActionCommand();
-
- if (CMD_CLEARLOG.equals(cmd)) clearLog();
- else if(CMD_CLOSELOG.equals(cmd)) setVisible(false);
-
- return;
- }
-
- }
-
}
package jp.sfjp.jindolf.log;
-import java.awt.Adjustable;
-import java.awt.EventQueue;
+import io.github.olyutorskii.quetexj.MvcFacade;
+import io.github.olyutorskii.quetexj.SwingLogHandler;
import java.util.logging.Handler;
import javax.swing.BorderFactory;
+import javax.swing.BoundedRangeModel;
import javax.swing.JPopupMenu;
+import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.Border;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
-import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.PlainDocument;
import jp.sfjp.jindolf.dxchg.TextPopup;
/**
* スクロールバー付きログ表示パネル。
- * 垂直スクロールバーは自動的に最下部へトラックする。
+ *
+ * <p>垂直スクロールバーは自動的に最下部へトラックする。
*/
@SuppressWarnings("serial")
-public class LogPanel extends JScrollPane {
+public final class LogPanel extends JScrollPane {
private static final Document DOC_EMPTY = new PlainDocument();
- private final Document document = new PlainDocument();
+ private final JTextArea textarea;
+ private final Document document;
private final Handler handler;
- private final JTextArea textarea = new JTextArea();
-
/**
* コンストラクタ。
+ *
+ * @param facade MvcFacade
*/
- public LogPanel(){
+ public LogPanel(MvcFacade facade){
super();
+ this.textarea = facade.getTextArea();
+ this.document = facade.getDocument();
+
if(LogUtils.hasLoggingPermission()){
- this.handler = new SwingDocHandler(this.document);
+ this.handler = new SwingLogHandler(this.document);
}else{
this.handler = null;
}
setViewportView(this.textarea);
- DocumentListener docListener = new DocWatcher();
- this.document.addDocumentListener(docListener);
+ JScrollBar vbar = getVerticalScrollBar();
+ BoundedRangeModel rangeModel = facade.getVerticalBoundedRangeModel();
+ vbar.setModel(rangeModel);
AncestorListener ancestorListener = new AncestorWatcher();
addAncestorListener(ancestorListener);
}
/**
- * 垂直スクロールバーをドキュメント下端に設定し、
- * ログの最新部を表示する。
- * 不可視状態なら何もしない。
- */
- private void showLastPos(){
- if(this.textarea.getDocument() != this.document) return;
-
- final Adjustable yPos = getVerticalScrollBar();
- EventQueue.invokeLater(new Runnable(){
- @Override
- public void run(){
- yPos.setValue(Integer.MAX_VALUE);
- return;
- }
- });
-
- return;
- }
-
- /**
* モデルとビューを連携させる。
- * スクロール位置は末端に。
*/
private void attachModel(){
if(this.textarea.getDocument() != this.document){
this.textarea.setDocument(this.document);
}
- showLastPos();
return;
}
return;
}
- /**
- * ログ内容をクリアする。
- */
- public void clearLog(){
- try{
- int docLength = this.document.getLength();
- this.document.remove(0, docLength);
- }catch(BadLocationException e){
- assert false;
- }
- return;
- }
-
/**
* 画面更新が必要な状態か監視し、必要に応じてモデルとビューを切り離す。
}
-
- /**
- * ドキュメント操作を監視し、スクロールバーを更新する。
- */
- private final class DocWatcher implements DocumentListener{
-
- /**
- * コンストラクタ。
- */
- DocWatcher(){
- super();
- return;
- }
-
- /**
- * {@inheritDoc}
- * @param event {@inheritDoc}
- */
- @Override
- public void changedUpdate(DocumentEvent event){
- showLastPos();
- return;
- }
-
- /**
- * {@inheritDoc}
- * @param event {@inheritDoc}
- */
- @Override
- public void insertUpdate(DocumentEvent event){
- showLastPos();
- return;
- }
-
- /**
- * {@inheritDoc}
- * @param event {@inheritDoc}
- */
- @Override
- public void removeUpdate(DocumentEvent event){
- showLastPos();
- return;
- }
-
- }
-
}
+++ /dev/null
-/*
- * Logging handler for Swing text component
- *
- * License : The MIT License
- * Copyright(c) 2011 olyutorskii
- */
-
-package jp.sfjp.jindolf.log;
-
-import java.awt.EventQueue;
-import java.util.logging.Formatter;
-import java.util.logging.Handler;
-import java.util.logging.Level;
-import java.util.logging.LogRecord;
-import java.util.logging.SimpleFormatter;
-import javax.swing.text.AttributeSet;
-import javax.swing.text.BadLocationException;
-import javax.swing.text.Document;
-
-/**
- * Swingテキストコンポーネント用データモデル
- * {@link javax.swing.text.Document}
- * に出力する{@link java.util.logging.Handler}。
- *
- * <p>スレッド間競合はEDTで解決される。
- *
- * <p>一定の文字数を超えないよう、古い記録は消去される。
- */
-public class SwingDocHandler extends Handler{
-
- private static final int DOCLIMIT = 100 * 1000; // 単位は文字
- private static final float CHOPRATIO = 0.9f;
- private static final int CHOPPEDLEN = (int) (DOCLIMIT * CHOPRATIO);
-
- static{
- assert DOCLIMIT > CHOPPEDLEN;
- }
-
-
- private final Document document;
-
-
- /**
- * ログハンドラの生成。
- * @param document ドキュメントモデル
- */
- public SwingDocHandler(Document document){
- super();
-
- this.document = document;
-
- Formatter formatter = new SimpleFormatter();
- setFormatter(formatter);
-
- return;
- }
-
- /**
- * ドキュメント末尾に文字列を追加する。
- *
- * <p>EDTから呼ばなければならない。
- *
- * @param logMessage 文字列
- */
- private void appendLog(String logMessage){
- try{
- this.document.insertString(this.document.getLength(),
- logMessage,
- (AttributeSet) null );
- }catch(BadLocationException e){
- assert false;
- }
- return;
- }
-
- /**
- * ドキュメント先頭部をチョップして最大長に納める。
- *
- * <p>EDTから呼ばなければならない。
- */
- private void chopHead(){
- int docLength = this.document.getLength();
- if(docLength <= DOCLIMIT) return;
-
- int offset = docLength - CHOPPEDLEN;
- try{
- this.document.remove(0, offset);
- }catch(BadLocationException e){
- assert false;
- }
-
- return;
- }
-
- /**
- * {@inheritDoc}
- * @param record {@inheritDoc}
- */
- @Override
- public void publish(LogRecord record){
- if( ! isLoggable(record) ){
- return;
- }
-
- Formatter formatter = getFormatter();
- final String message = formatter.format(record);
-
- EventQueue.invokeLater(new Runnable(){
- @Override
- public void run(){
- appendLog(message);
- chopHead();
- return;
- }
- });
-
- return;
- }
-
- /**
- * {@inheritDoc}
- * (何もしない)。
- */
- @Override
- public void flush(){
- return;
- }
-
- /**
- * {@inheritDoc}
- * ログ受け入れを締め切る。
- */
- @Override
- public void close(){
- setLevel(Level.OFF);
- flush();
- return;
- }
-
-}