'Java'에 해당되는 글 12건

  1. 2023.07.04 Java 와 다른 kotlin 문법
  2. 2023.02.26 JTextField, JLabel 에서 text 변경 이벤트 처리하기
  3. 2022.08.10 String split 사용할때 빈값 삭제 / 유지 예제 코드
  4. 2022.06.15 JLabel 텍스트 컬러 변경 하기
  5. 2022.02.17 프로세스 실행 후 종료 확인 코드
  6. 2022.01.06 Swing CustomLineBorder 만들기(top, left, bottom, right 지정하여 적용하기)
  7. 2021.12.28 JScrollPane 스크롤바 보이기/숨기기
  8. 2021.12.27 FlowLayout 에서 component 가 다음 라인으로 이동시 panel resize
  9. 2021.12.23 JComboBox 키 입력시 툴팁 보이기
  10. 2021.12.20 java swing 동적 툴팁, 멀티 라인 툴팁

Java 와 다른 kotlin 문법

프로그래밍/kotlin 2023. 7. 4. 01:07
반응형

kotlin을 사용하면서 java와 다른 점들과 샘플 코드들을 정리 한다.

0. main 함수가 클래스 안에 있을 필요가 없다.

main 함수를 클래스 없이 정의 하면 파일명으로 클래스가 생성되고 그안에 main 함수가 들어가게 된다.

1. 기본 타입들이 모두 클래스 이다.

기본 타입들은 java와 크게 다르지 않으나 모두 클래스 형태로 되어 있다.

2. 컴파일 시점에 기본 타입의 범위에 대한 체크가 이루어진다.

val a: Byte = 500 처럼 최대 값을 벗어나는 값으로 초기화를 할때 에러를 발생 시킨다.

초기 잘못된 타입에 대한 overflow를 예방 할수 있다.

3. 함수 정의는 fun, 변수 정의는 val, var을 앞에 붙인다.

fun foo(a: Int): Int   // fun 함수명(파라메터): 반환타입 형식으로 함수를 정의 한다.

변수앞에는 val, var을 붙이고 val 은 value로 변경 되지 않는 값, var은 variable로 변경 되는 값을 의미한다.

4. for 루프 사용하기

여러 스타일로 사용이 가능하다.

5. if, when

val c = if (a == 5) "a is 5" else "a is not 5" 처럼 if 문을 값으로 사용할수 있다. 이때 항상 else가 있어야 한다.

when은 switch 대신 사용한다고 생각하면 된다. default 대신 else를 사용한다.

when에서 사용하는 값은 기본 타입에서 클래스 객체까지 사용되고,

','를 사용하여 여러 값을 하나의 항목으로 묶을수 있다.

6. 멤버 변수 정의 하기

클래스 명 파라메터를 val, var로 정의를 하면 멤버 변수가 된다. data class 타입에서 주로 사용 된다.

멤버 변수를 전달 받은 파라메터로 초기화 가능 하고, init 블럭을 사용해서 초기화 할수도 있다.

var 변수의 경우 lateinit 을 사용하여 초기화 시점을 늦출수 있다.(사용하기 전에 초기화 하면 된다.)

lateinit은 val 변수에는 사용할수 없다. val은 값 변경이 되지 않아 생성시점에 초기화 되어야 한다.

7. getter, setter 정의 하기

Java 에서는 get~, set~ 메소드를 정의 해야 하나 kotlin에서는 멤버변수 밑에 get(), set(value)를 붙여 주면 된다.

간단하게 getter, setter가 정의 되고, 변수를 사용하듯이 값을 할당 하거나 사용하면 자동으로 set, get이 호출된다.

8. 상속 사용하기

kotlin의 class는 자바의 final class 이다. 상속이 되지 않는다.

kotlin의 open class는 자바의 class 이다. 상속이 가능하다.

overriding 가능한 함수는 앞에 "open"을 붙여준다. 사용할때는 "override" 를 앞에 붙인다.

추상 클래스는 "abstract" 키워드를 사용하여 정의 한다.

9. null 안정성 - 1

변수를 정의 할때 "?"를 붙여 null 사용여부를 결정한다.

var testName: String? = null

사용 할때 "!!"를 붙이면 java에서 사용할때처럼 null 값일 경우 null pointer exception이 발생한다.

"?"를 붙여서 사용한다면 null 값을 경우 아무런 동작을 하지 않는다.

dog.printName()   // compile error
cat2.printName()

둘다 if 문에서 null 체크를 했으나 하나는 컴파일 에러가 발생하고, 하나는 에러가 발생하지 않는다.

차이는 변수의 값이 if 문 이후 변경이 가능한지 여부이다.

dog은 멤버 변수로 멀티 스레드로 동작할 경우 if문을 지난 직후 다른 스레드에서 변경하는 상황이 발생할수 있다.

cat2는 로컬 변수로 함수내에서 변경이 불가능 하여 null 체크 후 "." 만으로 사용이 가능 하다.

10. null 안정성 - 2

dog?.let 은 dog이 null 이 아닐 경우에만 동작하는 블럭을 정의 하고 dog을 "it"을 사용하여 접근한다.

엘비스 연산자 "?:"는 if 문을 간소화 해준다.

11. data 클래스

class 명 앞에 data를 붙여 정의 하는 것으로 생성자 파라메터에 정의 값이 동일할 경우 == 연산시 true를 리턴한다.

동일한 객체인지를 확인 할때는 "==="를 사용한다.

data 클래스는 내부적으로 copy, equals 등 몇가지 메소드를 정의한다.(java 코드로 변환해서 비교 하기 추천)

12. 배열 사용하기

arrayOf 를 통해 값이 설정된 배열을 리턴한다.

배열의 값은 변경이 가능하다(List 와 비교 하면 어떤 의미인지 알수 있다.)

값 설정외 갯수를 정의 하는 방법도 있고 "IntArray(10) { index -> index }" 처럼 초기값을 설정하는 것이 가능하다.

Int 타입 처럼 숫자 관련 배열의 경우 sum, average  등의 자주 사용하는 연산 함수들이 추가 된다.

13. List, MutableList

주요 데이터 저장 타입에는 순서가 있는 List, 중복값 없는 Set, key 와 연결 되는 Map 이 있다.

이 타입들은 값 변경이 불가능하고 변경을 원할 경우 Mutable 이 붙어 있는 타입으로 정의 한다.(MutableList...)

14. Lambda 식

요즘 들어 개발 언어들을 보면 lambda 식을 지원한다는 내용이 자주 보인다.(c++, java 등)

그만큼 알고 사용하면 유용한 개발 방식이다.

주로 사용하는 방식은 생성된 객체의 변수를 다른 객체에서 접근하여 원하는 결과를 만들고 싶을때 사용한다.????

말하고 보니 설명이 쉽지 않은 부분이지만 여러 샘플 코드들을 보면서 이해 하길 추천한다.

예제 코드는 { num -> list.contains(num) } 가 내부 객체로 생성되고 그 참조가 LamdaTest 에 전달된다.

lambda 식이 내부 객체로 동작하는 부분을 이해하는게 중요하다.

15. coroutine 은 멀티 스레드가 아니다.

처음 봤을때는 가벼운 동시 작업 이라고 해서 멀티 스레드 개념으로 이해 했으나

context switching 과 관련이 없이 수행되는 동시 작업이라 동작이 완전히 다르다.

coroutine 용으로 사용되는 delay를 호출할 경우 그 제어권이 scope 관리로 넘어 간다.

delay 시간에 맞춰 각 coroutine 이 호출 될것으로 생각 하지만 멀티 스레드와 달리 호출이 될것에 대한 보장이 약하다.

coroutine 실행이 짧고 delay 가 호출되어 scope 관리로 넘어 갈 경우는 크게 문제가 되지 않지만

coroutine 실행이 길어질 경우 동일 scope내 coroutine들이 제시간에 실행 되는 것이 보장 되지 않는다.

sleep을 넣어 보면 sleep 끝날때까지 다른 coroutine 들이 동작 하지 않는다.

실행 시간이 짧은 비동기 실행이 필요할때 사용한다.

반응형
:

JTextField, JLabel 에서 text 변경 이벤트 처리하기

프로그래밍/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) {

        }
    }
}
반응형
:

String split 사용할때 빈값 삭제 / 유지 예제 코드

프로그래밍/java 2022. 8. 10. 22:26
반응형

String split 사용할때 빈값 삭제 / 유지 예제 코드

        String test1 = "abc|aa|bb|cc||";

        String[] strArray = test1.split("\\|");
        System.out.println("1. test1 length :" + strArray.length);

        for (String str : strArray) {
            System.out.println("1. test1 : " + str);
        }

        System.out.println("");

        strArray = test1.split("\\|", -1);
        System.out.println("2. test1 length :" + strArray.length);

        for (String str : strArray) {
            System.out.println("2. test1 : " + str);
        }

 

실행 결과

1. test1 length :4
1. test1 : abc
1. test1 : aa
1. test1 : bb
1. test1 : cc

2. test1 length :6
2. test1 : abc
2. test1 : aa
2. test1 : bb
2. test1 : cc
2. test1 : 
2. test1 :

https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#split-java.lang.String-int-

 

String (Java Platform SE 8 )

Compares two strings lexicographically. The comparison is based on the Unicode value of each character in the strings. The character sequence represented by this String object is compared lexicographically to the character sequence represented by the argum

docs.oracle.com

 

반응형
:

JLabel 텍스트 컬러 변경 하기

프로그래밍/java 2022. 6. 15. 22:22
반응형

JLabel 사용시 html 태그를 사용하여 컬러를 변경

package test.swing;

import javax.swing.*;
import java.awt.*;

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());
        String text = "<html><font color=#FF0000>test</font>test" +
                "<font style=\"color: #FFFFFF; background-color: #0000FF\">test</font></html>";
        JLabel label = new JLabel(text);
        label.setToolTipText("");
        label.setPreferredSize(new Dimension(100, 100));
        add(label);
        pack();
    }
}

 

실행결과

반응형
:

프로세스 실행 후 종료 확인 코드

프로그래밍/java 2022. 2. 17. 22:18
반응형

java에서 process 실행 후 결과 값을 stream 으로 계속 읽어 들일때 process 가 종료 되면

readline 등의 메소드가 block 이 걸릴수 있다.

이때 process를 체크하는 thread를 따로 생성 후 모니터링 하여 종료를 체크 하여 필요한 동작을 처리 한다.

https://beradrian.wordpress.com/2008/11/03/detecting-process-exit-in-java/

 

Detecting process exit in Java

If you develop a more complex system, the chances of being a heterogeneous are pretty big. So if you develop a system in Java, but you have to integrate all ready build parts with other technology,…

beradrian.wordpress.com

 

    public void run() {
        try {
            // wait for the process to finish
            process.waitFor();
            // invokes the listeners
            for (ProcessListener listener : listeners) {
                listener.processFinished(process);
            }
        } catch (InterruptedException e) {
        }
    }
반응형
:

Swing CustomLineBorder 만들기(top, left, bottom, right 지정하여 적용하기)

프로그래밍/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();
    }
}

실행결과

 

 

반응형
:

JScrollPane 스크롤바 보이기/숨기기

프로그래밍/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

반응형
:

FlowLayout 에서 component 가 다음 라인으로 이동시 panel resize

프로그래밍/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

반응형
:

JComboBox 키 입력시 툴팁 보이기

프로그래밍/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 swing 동적 툴팁, 멀티 라인 툴팁

프로그래밍/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-

 

JComponent (Java Platform SE 8 )

Returns true if a paint triggered on a child component should cause painting to originate from this Component, or one of its ancestors. Calling repaint(long, int, int, int, int) or paintImmediately(int, int, int, int) on a Swing component will result in ca

docs.oracle.com

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>");
반응형
: