|
프로그래밍/lognote 2023. 10. 28. 18:03
텍스트 로그 파일 보기(필터)
Logcat 보기(Online/Offline)
정규 표현식 필터
에이징 테스트 : 라인수에 따라 파일 분할 저장
Kotlin + swing
실행
- Windows : start javaw -Dfile.encoding=utf8 -Xmx1024m -jar LogNote.jar - Linux : java -Dfile.encoding=utf8 -Xmx2048m -jar LogNote.jar - Mac : java -Dfile.encoding=utf8 -Xmx2048m -jar LogNote.jar
version 0.3.5
- 버그 수정(프로세스 업데이트 중 멈추는 현상 수정)
- 정규 표현식 필터에도 컬러태그 적용 되도록 함
- logcat 레벨 설정 위치 메뉴바에서 하단 상태바로 이동
- 로그 뷰(full, filtered) 저장 기능 추가
version 0.3.4
- 버그 수정 - 최근 파일을 열때 이전에 사용한 필터 적용 여부 팝업 추가
- 프로세스 정보에 대한 업데이트 주기 설정 메뉴 추가
version 0.3.3
- logcat 수신 모드일때 key 입력으로 포커스 이동시 툴팁에 로그 프로세스 정보 출력
- 타이틀 바에 실행 모드 표시
- 최근 파일 저장 / 불러오기(북마크 저장)
- 코드 리팩토링
- 로그 필터 콤보박스에 '#' 입력시 사용 가능한 컬러 리스트 출력
version 0.3.2
- logcat 로그가 아닌 로그 파일에 필터가 적용되지 않는 현상 수정
- 코드 리팩토링
- 최근 파일 저장 / 불러오기(파일 별 필터 저장)
- 스크롤백 제한으로 로그 파일 삭제 될때 화면이 밀려올라가는 현상 수정
- logcat 수신 모드일때 툴팁에 로그 프로세스 정보 출력
- 업데이트 체크 메뉴 추가
version 0.3.1
- 단축키 로직 정리
- 필터 추가시 컬러 태그 적용 메뉴 추가
- 버그 수정
version 0.3.0
- 버튼에 아이콘 추가
- 로그뷰에서 보여지는 로그 모드(Open, Adb, Cmd, Follow) 에 따라 타이틀바 변경
- 버그 수정
version 0.2.9
- default font 변경 : dialog -> dialoginput
- 정규표현식 파싱 에러 발생시 텍스트 컬러 변경(알림)
- 검색에서 shift - enter 입력시 이전 항목으로 이동
- 버그 수정
version 0.2.8
- logcat 명령 변경 기능 추가
- 검색 기능 추가
Ctrl + F : 검색바 보이기 ESC : 검색바 숨기기 F3 : 이전 항목으로 이동 F4 : 다음 항목으로 이동 필터 또는 전체 로그 뷰 클릭 :검색 타겟 뷰 설정
version 0.2.7
- 필터 아이템별 컬러 설정 기능 추가
- Ctrl + 필터버튼 실행시 필터 내용 붙이기 기능 추가
version 0.2.6
- UI 및 로그 컬러 관련 설정 합침
- 내장 색상표 적용 UI 변경
- 버그 수정
version 0.2.5
- UI 콤포넌트 폰트 사이즈 변경 기능 추가
- 내장 색상표 기능 추가(light, dark)
- 필터 / bold 텍스트 FG / BG 컬러 설정
- 저장 파일 default prefix "LogNote" 로 설정
- 필터 / bold 텍스트 겹칠 경우 bold 컬러 적용
- 안정성 개선??
version 0.2.4
- 환경 변수 "LOGNOTE_HOME" 참조 하여 config 파일 저장 위치 설정
- FlatLaf 적용(https://github.com/JFormDesigner/FlatLaf)
version 0.2.3
- 필터 입력 콤보박스 멀티 라인 적용
- 로그 화면 비율 조절시 일정 크기 이하로 변경 되지 않는 현상 수정
- 코드 정리
version 0.2.2
- 디바이스 재부팅 등으로 연결이 끊겼을때 연결 재시도 로직 추가
- 설정 변경시 즉시 저장(창닫을 필요 없음)
version 0.2.1
- 멀티 라인 북마크 기능 추가(여러라인 선택 후 동시 북마크)
- 컬러 세팅 아이템 추가
version 0.2.0
- adb 에서 logcat 읽기 속도 개선
- 필터 적용 속도 개선
- 컬러 세팅 아이템 추가
version 0.1.9
- 자주 사용하는 필터 테이블 바에 추가 가능 하도록 수정
- 필터 관리 창에서 순서 변경 기능 추가
- 자주 사용하는 명령 관리 기능 추가
version 0.1.8
- 상태바 tooltip 에 열린 파일 리스트 출력
- adb 연결 보기 실패시 에러 팝업 출력
- 필터 tooltip 에 include, exclude 항목 출력
version 0.1.7
- 사용하지 않는 필터 콤보박스 숨기기
- ESC 키 입력시 다이얼로그 닫기
version 0.1.6
- 여러파일 동시 열기
- tooltip 추가
- windows drag & drop 개선
- 스크롤백 제한으로 인한 로그 삭제 일시 중지 기능 추가
version 0.1.5
- 로그 컬러 세팅 추가
- 필터 로그뷰에서 커서 이동시 전체 로그뷰 커서 이동 개선
- 스크롤백 라인 제한으로 인한 로그 삭제시 뷰 동작 개선
version 0.1.4 - 설정에서 폰트 변경시 즉시 적용 - 필터 저장 및 가져오기
version 0.1.1 - 팝업메뉴 추가 - 대소문자 구분
version 0.0.1 - 정규 표현식 필터 - On/Off line 로그 뷰
프로그래밍/java 2023. 2. 26. 22:58
JLabel : PropertyChangeListener
JTextField : DocumentListener
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
public class TestClass {
JLabel mLabel = new JLabel("TEST");
JTextField mTextField = new JTextField("TEST");
TestClass() {
mLabel.addPropertyChangeListener(new MyChangeListener());
mTextField.getDocument().addDocumentListener(new MyDocumentListener());
}
private class MyChangeListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if ("text".equals(evt.getPropertyName())) {
}
}
}
private class MyDocumentListener implements DocumentListener {
@Override
public void insertUpdate(DocumentEvent e) {
}
@Override
public void removeUpdate(DocumentEvent e) {
}
@Override
public void changedUpdate(DocumentEvent e) {
}
}
}
프로그래밍/java 2022. 1. 6. 22:58
생성시 지정된 면만 border 적용 하도록 border 재정의 함
package test.swing;
import javax.swing.*;
import javax.swing.border.AbstractBorder;
import java.awt.*;
// Custom Line border
public class MainTest {
public static void main(String[] args) {
MainUI mainUI = new MainUI();
mainUI.setVisible(true);
}
}
class CustomLineBorder extends AbstractBorder
{
public static final int TOP = 0x1;
public static final int LEFT = 0x2;
public static final int BOTTOM = 0x4;
public static final int RIGHT = 0x8;
private Color mColor;
private int mThickness;
private int mTarget;
public CustomLineBorder(Color colour, int thickness, int target)
{
mColor = colour;
mThickness = thickness;
mTarget = target;
}
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height)
{
if (g != null)
{
g.setColor(mColor);
if ((mTarget & TOP) != 0) {
for (int i = 0; i < mThickness; i++) {
g.drawLine(x, y + i, width, y + i);
}
}
if ((mTarget & LEFT) != 0) {
for (int i = 0; i < mThickness; i++) {
g.drawLine(x + i, y, x + i, height);
}
}
if ((mTarget & BOTTOM) != 0) {
for (int i = 0; i < mThickness; i++) {
g.drawLine(x, height - i - 1, width, height - i - 1);
}
}
if ((mTarget & RIGHT) != 0) {
for (int i = 0; i < mThickness; i++) {
g.drawLine(width - i - 1, y, width - i - 1, height);
}
}
}
}
@Override
public Insets getBorderInsets(Component c)
{
return (getBorderInsets(c, new Insets(0, 0, 0, 0)));
}
@Override
public Insets getBorderInsets(Component c, Insets insets)
{
insets.top = 0;
insets.left = 0;
insets.bottom = 0;
insets.right = 0;
if ((mTarget & TOP) != 0) {
insets.top = mThickness;
}
if ((mTarget & LEFT) != 0) {
insets.left = mThickness;
}
if ((mTarget & BOTTOM) != 0) {
insets.bottom = mThickness;
}
if ((mTarget & RIGHT) != 0) {
insets.right = mThickness;
}
return insets;
}
@Override
public boolean isBorderOpaque()
{
return true;
}
}
class MainUI extends JFrame {
MainUI() {
setPreferredSize(new Dimension(400, 420));
JPanel pane = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 20));
pane.setBackground(new Color(0x85, 0x85, 0x85));
JLabel label = new JLabel("Red, 1, TOP");
label.setPreferredSize(new Dimension(300, 40));
label.setOpaque(true);
label.setBackground(Color.WHITE);
label.setBorder(new CustomLineBorder(Color.RED, 1, CustomLineBorder.TOP));
pane.add(label);
label = new JLabel("Red, 5, LEFT");
label.setPreferredSize(new Dimension(300, 40));
label.setOpaque(true);
label.setBackground(Color.WHITE);
label.setBorder(new CustomLineBorder(Color.RED, 5, CustomLineBorder.LEFT));
pane.add(label);
label = new JLabel("Red, 5, Bottom");
label.setPreferredSize(new Dimension(300, 40));
label.setOpaque(true);
label.setBackground(Color.WHITE);
label.setBorder(new CustomLineBorder(Color.RED, 5, CustomLineBorder.BOTTOM));
pane.add(label);
label = new JLabel("Red, 15, Right");
label.setPreferredSize(new Dimension(300, 40));
label.setOpaque(true);
label.setBackground(Color.WHITE);
label.setBorder(new CustomLineBorder(Color.RED, 15, CustomLineBorder.RIGHT));
pane.add(label);
label = new JLabel("Blue, 5, TOP LEFT");
label.setPreferredSize(new Dimension(300, 40));
label.setOpaque(true);
label.setBackground(Color.WHITE);
label.setBorder(new CustomLineBorder(Color.BLUE, 5, CustomLineBorder.LEFT | CustomLineBorder.TOP));
pane.add(label);
label = new JLabel("Blue, 5, TOP RIGHT BOTTOM");
label.setPreferredSize(new Dimension(300, 40));
label.setOpaque(true);
label.setBackground(Color.WHITE);
label.setBorder(new CustomLineBorder(Color.BLUE, 5, CustomLineBorder.TOP | CustomLineBorder.RIGHT | CustomLineBorder.BOTTOM));
pane.add(label);
add(pane);
pack();
}
}
실행결과
프로그래밍/java 2021. 12. 28. 22:52
setHorizontalScrollBarPolicy, setVerticalScrollBarPolicy 를 사용하여 설정
package test.swing;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
// JScrollPane scrollbar show / hide
public class MainTest {
public static void main(String[] args) {
MainUI mainUI = new MainUI();
mainUI.setVisible(true);
}
}
class MainUI extends JFrame {
JScrollPane scrollPane1 = null;
JScrollPane scrollPane2 = null;
JScrollPane scrollPane3 = null;
JTable table1 = null;
JTable table2 = null;
JTable table3 = null;
DefaultTableModel tableModel = null;
MainUI() {
setPreferredSize(new Dimension(400, 600));
setLayout(new GridLayout(3, 1));
System.out.println("JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED = " + JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
System.out.println("JScrollPane.HORIZONTAL_SCROLLBAR_NEVER = " + JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
System.out.println("JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS = " + JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
System.out.println("JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED = " + JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
System.out.println("JScrollPane.VERTICAL_SCROLLBAR_NEVER = " + JScrollPane.VERTICAL_SCROLLBAR_NEVER);
System.out.println("JScrollPane.VERTICAL_SCROLLBAR_ALWAYS = " + JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
table1 = new JTable();
tableModel = (DefaultTableModel) table1.getModel();
tableModel.addColumn("Column");
tableModel.addRow(new Object[]{"SCROLLBAR_AS_NEEDED"});
scrollPane1 = new JScrollPane(table1);
add(scrollPane1);
System.out.println("default h policy = " + scrollPane1.getHorizontalScrollBarPolicy() + ", v policy = " + scrollPane1.getVerticalScrollBarPolicy());
table2 = new JTable();
tableModel = (DefaultTableModel) table2.getModel();
tableModel.addColumn("Column");
tableModel.addRow(new Object[]{"HORIZONTAL_SCROLLBAR_NEVER"});
tableModel.addRow(new Object[]{"VERTICAL_SCROLLBAR_ALWAYS"});
scrollPane2 = new JScrollPane(table2);
scrollPane2.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane2.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
add(scrollPane2);
table3 = new JTable();
tableModel = (DefaultTableModel) table3.getModel();
tableModel.addColumn("Column");
tableModel.addRow(new Object[]{"HORIZONTAL_SCROLLBAR_ALWAYS"});
tableModel.addRow(new Object[]{"VERTICAL_SCROLLBAR_NEVER"});
scrollPane3 = new JScrollPane(table3);
scrollPane3.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane3.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
add(scrollPane3);
pack();
}
}
실행결과
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED = 30
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER = 31
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS = 32
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED = 20
JScrollPane.VERTICAL_SCROLLBAR_NEVER = 21
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS = 22
default h policy = 30, v policy = 20
프로그래밍/java 2021. 12. 27. 22:31
Resize 이벤트 발생시 JPanel의 높이를 마지막 component 에 맞추는 코드
package test.swing;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
// resize panel
public class MainTest {
public static void main(String[] args) {
MainUI mainUI = new MainUI();
mainUI.setVisible(true);
}
}
class MainUI extends JFrame {
FlowLayout flowLayout = new FlowLayout(FlowLayout.LEFT, 0, 0);
JPanel resizePane = new JPanel(flowLayout);
JButton testBtn1 = new JButton("TEST 1");
JButton testBtn2 = new JButton("TEST 2");
JButton testBtn3 = new JButton("TEST 3");
JButton testBtn4 = new JButton("TEST 4");
JButton testBtn5 = new JButton("TEST 5");
JComponent lastComponent = testBtn5;
MainUI() {
setPreferredSize(new Dimension(500, 300));
setLayout(new BorderLayout());
resizePane.setBackground(Color.BLUE);
resizePane.addComponentListener(new ComponentAdapter() {
Point prevPoint = null;
@Override
public void componentResized(ComponentEvent e) {
super.componentResized(e);
if (prevPoint == null || prevPoint.y != lastComponent.getLocation().y) {
System.out.println("lastComonent moved to " + lastComponent.getLocation());
resizePane.setPreferredSize(new Dimension(resizePane.getPreferredSize().width, lastComponent.getLocation().y + lastComponent.getHeight()));
resizePane.updateUI();
}
prevPoint = lastComponent.getLocation();
}
});
resizePane.add(testBtn1);
resizePane.add(testBtn2);
resizePane.add(testBtn3);
resizePane.add(testBtn4);
resizePane.add(testBtn5);
add(resizePane, BorderLayout.NORTH);
JPanel pane = new JPanel();
pane.add(new JLabel("TEST TEST"));
add(pane, BorderLayout.CENTER);
pack();
}
}
최초 실행
JPanel 크기 변경 1
JPanel 크기 변경 2
프로그래밍/java 2021. 12. 23. 22:00
JComboBox 에 key listener 설정 하여 키 발생시 툴팁을 보여주는 코드
package test.swing;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
// key event tooltip
public class MainTest {
public static void main(String[] args) {
MainUI mainUI = new MainUI();
mainUI.setVisible(true);
}
}
class TestComboBox extends JComboBox {
JTextField mTf = null;
public TestComboBox() {
super();
mTf = (JTextField) editor.getEditorComponent();
mTf.setToolTipText("TextField : ");
mTf.addKeyListener(new KeyHandler());
}
class KeyHandler extends KeyAdapter {
@Override
public void keyReleased(KeyEvent e) {
// set tooltip
mTf.setToolTipText("TextField : " + mTf.getText());
// show tooltip
ToolTipManager.sharedInstance().mouseMoved(new MouseEvent(mTf, 0, 0, 0,0, 0, 0, false));
super.keyReleased(e);
}
}
}
class MainUI extends JFrame {
MainUI() {
setPreferredSize(new Dimension(400, 300));
setLayout(new FlowLayout());
TestComboBox combo = new TestComboBox();
combo.setToolTipText("ComboBox");
combo.setEditable(true);
add(combo);
pack();
}
}
프로그래밍/java 2021. 12. 20. 22:28
getToolTipText 메소드 override 로 구현
https://docs.oracle.com/javase/8/docs/api/javax/swing/JComponent.html#getToolTipText-java.awt.event.MouseEvent-
package test.swing;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
// dynamic tooltip
public class MainTest {
public static void main(String[] args) {
MainUI mainUI = new MainUI();
mainUI.setVisible(true);
}
}
class ToolTipButton extends JButton {
boolean mIsNum = true;
public ToolTipButton(String text) {
super(text);
}
// 1. use setToolTipText
@Override
public String getToolTipText(MouseEvent event) {
if (mIsNum) {
setToolTipText("0123456789");
}
else {
setToolTipText("ABCDEFG");
}
mIsNum = !mIsNum;
return super.getToolTipText(event);
}
// 2. return text directly
@Override
public String getToolTipText(MouseEvent event) {
String text = "";
if (mIsNum) {
text = "0123456789";
}
else {
text = "ABCDEFG";
}
mIsNum = !mIsNum;
return text;
}
}
class MainUI extends JFrame {
MainUI() {
setPreferredSize(new Dimension(400, 300));
setLayout(new FlowLayout());
JButton button = new ToolTipButton("TEST");
button.setToolTipText("");
button.setPreferredSize(new Dimension(100, 100));
add(button);
pack();
}
}
멀티라인 툴팁
setToolTipText("<html>a<br>b</html>");
프로그래밍/lognote 2021. 12. 14. 20:34
version 0.1.7
- 사용하지 않는 필터 콤보박스 숨기기
- ESC 키 입력시 다이얼로그 닫기
version 0.1.6
- 여러파일 동시 열기
- tooltip 추가
- windows drag & drop 개선
- 스크롤백 제한으로 인한 로그 삭제 일시 중지 기능 추가
version 0.1.5
- 로그 컬러 세팅 추가
- 필터 로그뷰에서 커서 이동시 전체 로그뷰 커서 이동 개선
- 스크롤백 라인 제한으로 인한 로그 삭제시 뷰 동작 개선
version 0.1.4 - 설정에서 폰트 변경시 즉시 적용 - 필터 저장 및 가져오기
version 0.1.1 - 팝업메뉴 추가 - 대소문자 구분
version 0.0.1 - 정규 표현식 필터 - On/Off line 로그 뷰
프로그래밍/java 2021. 12. 13. 21:00
ESC 입력시 창 닫기
package test.swing;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowEvent;
public class MainTest {
public static void main(String[] args) {
MainUI mainUI = new MainUI();
mainUI.setVisible(true);
}
}
class MainUI extends JFrame {
MainUI() {
setPreferredSize(new Dimension(400, 300));
setLayout(new FlowLayout());
JButton button = new JButton("TEST");
button.setPreferredSize(new Dimension(100, 100));
add(button);
pack();
KeyStroke escStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
String actionMapKey = getClass().getName() + ":WINDOW_CLOSING";
Action closingAction = new AbstractAction() {
public void actionPerformed(ActionEvent event) {
MainUI.this.dispatchEvent(new WindowEvent(MainUI.this, WindowEvent.WINDOW_CLOSING));
}
};
installKeyStroke(this, escStroke, actionMapKey, closingAction);
}
public void installKeyStroke(final RootPaneContainer container, final KeyStroke stroke, final String actionMapKey, final Action action) {
JRootPane rootPane = container.getRootPane();
rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(stroke, actionMapKey);
rootPane.getActionMap().put(actionMapKey, action);
}
}
프로그래밍/lognote 2021. 11. 24. 16:26
|