Ten wpis napisałem korzystając z materiałów udostępnionych przez córkę.
Jak wiemy – w języku Java podpowiedzi można formatować przy użyciu HTML.
Podpowiedzi można też formatować bez użycia HTML. W tym wpisie właśnie to pokazuję.
Klasy
Aby móc formatować podpowiedzi należy przede wszystkim przygotować 2 klasy:
RectToolTip
RectToolTipUI
Potem tworzymy klasę przycisku MyButton
, w którym nadpisujemy metodę createToolTip()
.
W klasach:
Main1
– pokazuje niesformatowaną podpowiedź w normalnym przycisku JButtonMain2
do przyciskuMyButton
dodajemy podpowiedź przy użyciu metodysetTooltip(Tooltip)
Main3
– przy tworzeniu normalnego JButton nadpisujemy metodęcreateToolTip()
RectToolTip.java
package tooltip1; import javax.swing.*; public class RectToolTip extends JToolTip { private static final long serialVersionUID = 2381804711089908434L; public RectToolTip() { setUI(new RectToolTipUI()); } }
RectToolTipUI
package tooltip1; import java.awt.*; import java.util.*; import javax.swing.*; import javax.swing.plaf.metal.*; public class RectToolTipUI extends MetalToolTipUI { private String[] tokeny; @SuppressWarnings("unused") private int maxWidth = 0; private int rectW = 0; @Override public void paint(Graphics g, JComponent c) { FontMetrics fm = g.getFontMetrics(g.getFont()); Dimension size = c.getSize(); g.setColor(c.getBackground()); g.fillRect(0, 0, size.width, size.height); g.setFont(c.getFont()); g.setColor(c.getForeground()); int curX = 5;//polozenie tekstu na scenie int curY = 15;//polozenie tekstu na scenie int akt;//szerokosc aktualnie wypisywanego slowa @SuppressWarnings("unused") int rows = 1;//liczba linii tekstu for (String s : tokeny) { akt = fm.stringWidth(s);//sprawdza szerokosc stringu //w pikselach if ((curX + akt) < rectW + 5) {//jesli sie miesci w ramce g.drawString(s, curX, curY);//to wypisuje curX += akt;//zmienia pozycje "glowicy" } else {//jesli sie nie miesci curX = 5;//to przenosi "glowice" na poczatk curY += fm.getHeight();//i do nowego wiersza rows++;//dodaje nowy rzad g.drawString(s, curX, curY);//wypisuje string curX += akt;//zmienia pozycje "glowicy" } } } @Override public Dimension getPreferredSize(JComponent c) { FontMetrics fm = c.getFontMetrics(c.getFont()); String tipText = ((JToolTip) c).getTipText(); if (tipText == null) { tipText = ""; } StringTokenizer st = new StringTokenizer(tipText, " ", true); int tokNum = st.countTokens(); tokeny = new String[tokNum]; int i = -1; int maxStrLen = 0; String maxString = null; while (st.hasMoreTokens()) { i++; String val = st.nextToken();//pobiera token tokeny[i] = val;//przypisuje token do tablicy int valLen = val.length();//sprawdza ilosc znakow w tokenie if (valLen > maxStrLen) {//sprawdza czy token jest najdluzszy maxStrLen = valLen;//jesli tak to ustawia dlugosc maxString = tokeny[i];//i pobiera ten string } } int textH = fm.getHeight(); int textW = fm.stringWidth(tipText); int textArea = textH * textW; rectW = (int) Math.round(Math.sqrt(textArea / 0.62)); int len1 = fm.stringWidth(maxString); if (rectW < len1 + 5) { rectW = len1 + 10; } int curX = 5;//polozenie tekstu na scenie @SuppressWarnings("unused") int curY = 15;//polozenie tekstu na scenie int akt;//szerokosc aktualnie wypisywanego slowa int rows = 1;//liczba linii tekstu for (i = 0; i < tokeny.length; i++) { akt = fm.stringWidth(tokeny[i]);//sprawdza szerokosc stringu //w pikselach if ((curX + akt) < rectW + 5) {//jesli sie miesci w ramce curX += akt;//zmienia pozycje "glowicy" } else {//jesli sie nie miesci curX = 5;//to przenosi "glowice" na poczatk curY += fm.getHeight();//i do nowego wiersza rows++;//dodaje nowy rzad curX += akt;//zmienia pozycje "glowicy" } } int dismissDelay = 4000; if (rows > 4) { dismissDelay = rows * 1300; } ToolTipManager.sharedInstance().setDismissDelay(dismissDelay); return new Dimension(rectW + 8, rows * fm.getHeight() + 5); } }
MyButton.java
package tooltip1; import java.awt.*; import javax.swing.*; public class /**/MyButton extends JButton { private static final long serialVersionUID = 3602182470147405262L; MyButton() { super(); } MyButton(Action a) { super(a); } MyButton(Icon icon) { super(icon); } MyButton(String text) { super(text); } MyButton(String text, Icon icon) { super(text, icon); } @Override public JToolTip createToolTip() { RectToolTip tip = new RectToolTip(); tip.setComponent(this); tip.setBackground(Color.GREEN); tip.setForeground(Color.BLUE); tip.setFont(new Font("Dialog", Font.ITALIC, 14)); return tip; } }
Main1.java
package tooltip1; import javax.swing.*; import java.awt.*; /** * ramka + panel */ public class Main1 extends JFrame { private static final long serialVersionUID = 1L; public static void main(String[] args) { SwingUtilities.invokeLater(() -> new Main1()); } public Main1() { setLayout(null); setPreferredSize(new Dimension(800, 800)); int frameHeight = 800; int frameWidth = 800; setBounds((Toolkit.getDefaultToolkit().getScreenSize().width / 2) - (frameWidth / 2), (Toolkit.getDefaultToolkit() .getScreenSize().height / 2) - (frameHeight / 2), frameWidth, frameHeight); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle("Ramka Graficzna"); // setResizable(false); JPanel panel = new JPanel(); panel.setLayout(null); panel.setBounds(0, 0, frameWidth, frameHeight); JButton but = new JButton("Button"); String str = "Jest to moment konkretyzowania planów. Wskazuje na początek dziaia albo nowy fakt w życiu pytającego. Należy uważnie rozważyć karty sąsiednie. Karta ta oznacza przede wszystkim pracę, plany i dzieci. Może wskazywać na początek nowego, ważnego etapu w życiu pytającego. Spotkanie z drugim człowiekiem (w towarzystwie karty Diabeł - akt seksualny). Niezależność jest korzystna dla pytającego. Pytający może narzucić swoją wolę, kontynuować wysiłek i zrealizować plany. Karta ta często reprezentuje młodą osobę (o ile nie występuje w towarzystwie karty Pustelnik), albo pytającego, o ile nie przekroczył czterdziestki. Mag w sąsiedztwie karty Słoñce reprezentuje miłość męską."; but.setToolTipText(str); but.setBounds(100, 100, 100, 40); panel.add(but); add(panel); setVisible(true); } }
Efektem najechania kurorem myszy na przycisk jest:
Main2.java
package tooltip1; import java.awt.*; import javax.swing.*; /** * ramka + panel */ public class Main2 extends JFrame{ private static final long serialVersionUID = 1L; public static void main(String[] args) { SwingUtilities.invokeLater(() -> new Main2()); } public Main2(){ setLayout(null); setPreferredSize(new Dimension(800, 800)); int frameHeight = 800; int frameWidth = 800; setBounds((Toolkit.getDefaultToolkit().getScreenSize().width / 2) - (frameWidth / 2), (Toolkit.getDefaultToolkit() .getScreenSize().height / 2) - (frameHeight / 2), frameWidth, frameHeight); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle("Ramka Graficzna"); // setResizable(false); JPanel panel = new JPanel(); panel.setLayout(null); panel.setBounds(0, 0, frameWidth, frameHeight); MyButton but = new MyButton("Button"); String str = "Jest to moment konkretyzowania planów. Wskazuje na początek dziaia albo nowy fakt w życiu pytającego. Należy uważnie rozważyć karty sąsiednie. Karta ta oznacza przede wszystkim pracę, plany i dzieci. Może wskazywać na początek nowego, ważnego etapu w życiu pytającego. Spotkanie z drugim człowiekiem (w towarzystwie karty Diabeł - akt seksualny). Niezależność jest korzystna dla pytającego. Pytający może narzucić swoją wolę, kontynuować wysiłek i zrealizować plany. Karta ta często reprezentuje młodą osobę (o ile nie występuje w towarzystwie karty Pustelnik), albo pytającego, o ile nie przekroczył czterdziestki. Mag w sąsiedztwie karty Słoñce reprezentuje miłość męską."; but.setToolTipText(str); but.setBounds(100, 100, 100, 40); panel.add(but); add(panel); setVisible(true); } }
Efektem uruchomienia i najechania kursorem myszy na przycisk jest:
Main3.java
package tooltip1; import java.awt.*; import javax.swing.*; /** * ramka + panel */ public class Main3 extends JFrame { private static final long serialVersionUID = 1L; public static void main(String[] args) { SwingUtilities.invokeLater(() -> new Main3()); } public Main3() { setLayout(null); setPreferredSize(new Dimension(800, 800)); int frameHeight = 800; int frameWidth = 800; setBounds((Toolkit.getDefaultToolkit().getScreenSize().width / 2) - (frameWidth / 2), (Toolkit.getDefaultToolkit() .getScreenSize().height / 2) - (frameHeight / 2), frameWidth, frameHeight); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle("Ramka Graficzna"); // setResizable(false); JPanel panel = new JPanel(); panel.setLayout(null); panel.setBounds(0, 0, frameWidth, frameHeight); JButton but = new JButton("Button") { private static final long serialVersionUID = -50399866112532871L; @Override public JToolTip createToolTip() { RectToolTip tip = new RectToolTip(); tip.setComponent(this); tip.setBackground(Color.YELLOW); tip.setForeground(Color.RED); tip.setFont(new Font("Dialog", Font.ITALIC, 12)); return tip; } }; String str = "Jest to moment konkretyzowania planów. Wskazuje na początek działania albo nowy fakt w życiu pytającego. Należy uważnie rozważyć karty sąsiednie. Karta ta oznacza przede wszystkim pracę, plany i dzieci. Może wskazywać na początek nowego, ważnego etapu w życiu pytającego. Spotkanie z drugim człowiekiem (w towarzystwie karty Diabeł - akt seksualny). Niezależność jest korzystna dla pytającego. Pytający może narzucić swoją wolę, kontynuować wysiłek i zrealizować plany. Karta ta często reprezentuje młodą osobę (o ile nie występuje w towarzystwie karty Pustelnik), albo pytającego, o ile nie przekroczył czterdziestki. Mag w sąsiedztwie karty Słońce reprezentuje miłość męską."; but.setToolTipText(str); but.setBounds(100, 100, 100, 40); panel.add(but); add(panel); setVisible(true); } }
Efektem najechania kursorem myszy na przycisk jest: