Skip to content

Instantly share code, notes, and snippets.

@swimmesberger
Created December 4, 2018 14:00
Show Gist options
  • Save swimmesberger/9b7f1d6fecee005bb7587286d4e65399 to your computer and use it in GitHub Desktop.
Save swimmesberger/9b7f1d6fecee005bb7587286d4e65399 to your computer and use it in GitHub Desktop.
package net.miginfocom.examples;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import net.miginfocom.swing.MigLayout;
public class HtmlLabelBugTest {
public static void main(String[] args) throws Exception {
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
createTestFrame();
}
private static void createTestFrame() {
JFrame f1 = new HtmlLabelBugFrame();
f1.setVisible(true);
}
@SuppressWarnings("serial")
private static class HtmlLabelBugFrame extends JFrame {
private final AnimalDTO[] shuffleAnimals;
private final HtmlLabelBugPanel bugPanel;
private volatile int currentShuffle;
public HtmlLabelBugFrame() {
super(HtmlLabelBugTest.class.getSimpleName());
this.shuffleAnimals = new AnimalDTO[] {
new AnimalDTO("9b4c3a229ecb436bf", "very very very long string",
"another very very very long string"),
new AnimalDTO("995689c0b627d9621", "short s", "short n") };
bugPanel = new HtmlLabelBugPanel();
JButton changeButton = new JButton(new AbstractAction("Switch") {
@Override
public void actionPerformed(ActionEvent arg0) {
AnimalDTO animal = shuffleAnimals[currentShuffle];
bugPanel.setAnimal(animal);
System.out.println(animal.toCodeString());
currentShuffle++;
if (currentShuffle >= shuffleAnimals.length) {
currentShuffle = 0;
}
}
});
JPanel buttonPanel = new JPanel(new FlowLayout());
buttonPanel.add(changeButton);
JPanel testPanel = new JPanel(new BorderLayout());
testPanel.add(bugPanel, BorderLayout.CENTER);
testPanel.add(buttonPanel, BorderLayout.SOUTH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().add(testPanel);
setSize(new Dimension(720, 250));
setLocationRelativeTo(null);
shuffleAnimal();
}
private void shuffleAnimal() {
AnimalDTO animal = shuffleAnimals[currentShuffle];
bugPanel.setAnimal(animal);
System.out.println(animal.toCodeString());
System.out.println("Height: " + bugPanel.getHeight());
currentShuffle++;
if (currentShuffle >= shuffleAnimals.length) {
currentShuffle = 0;
}
}
}
@SuppressWarnings("serial")
private static class HtmlLabelBugPanel extends JPanel {
private final JLabel bornTf;
private final JLabel deliveredTf;
private final JLabel animalname;
private final JLabel animalLabel;
public HtmlLabelBugPanel() {
super(new MigLayout("debug, insets 20 10 20 10", "[]25[]10[]20[]10[]20[]10[]", "[]15[]5[]"));
Icon testIcon = new Icon() {
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
g.setColor(Color.RED);
g.fillRect(x, y, this.getIconWidth(), this.getIconHeight());
}
@Override
public int getIconWidth() {
return 64;
}
@Override
public int getIconHeight() {
return 64;
}
};
JLabel icon = new JLabel(testIcon);
add(icon, "spany");
animalLabel = new HtmlLabel("Animal:");
animalLabel.setFont(animalLabel.getFont().deriveFont(24f));
add(animalLabel, "spanx, split 2");
animalname = new HtmlLabel();
animalname.setFont(animalLabel.getFont().deriveFont(Font.BOLD));
add(animalname, "growx, al left, wrap");
bornTf = new HtmlLabel();
bornTf.setFont(bornTf.getFont().deriveFont(Font.BOLD));
deliveredTf = new HtmlLabel();
deliveredTf.setFont(bornTf.getFont());
JLabel bornLabel = new HtmlLabel("Born on:");
JLabel deliveredLabel = new HtmlLabel("Delivered on:");
add(bornLabel);
add(bornTf);
add(deliveredLabel);
add(deliveredTf, "wrap");
}
public void setAnimal(AnimalDTO animal) {
animalLabel.setVisible(true);
animalname.setText(animal == null ? "" : animal.getDisplayName());
String bornOn = animal == null ? null : animal.getDateOfBirth();
String deliveredOn = animal == null ? null : animal.getDeliveryDate();
if (bornOn == null) {
bornTf.setText("?");
} else {
bornTf.setText(bornOn);
}
if (deliveredOn == null) {
deliveredTf.setText("?");
} else {
deliveredTf.setText(deliveredOn);
}
this.repaint();
}
}
@SuppressWarnings("serial")
private static class HtmlLabel extends JLabel {
private static final boolean WITH_HTML = true;
public HtmlLabel(String text) {
super(text);
}
@SuppressWarnings("unused")
public HtmlLabel(Icon image) {
super(image);
}
public HtmlLabel() {
super();
}
@Override
public void setText(String text) {
if (!WITH_HTML) {
super.setText(text);
} else {
super.setText("<html><p>" + text + "</p></html>");
}
}
@Override
public int getBaseline(int width, int height) {
int origBaseLine = super.getBaseline(width, height);
System.out.println("Input: w:" + width + ", h:" + height);
System.out.println("Baseline: " + origBaseLine);
return origBaseLine;
}
}
private static class AnimalDTO {
private final String name;
private final String bornOn;
private final String deliveredOn;
public AnimalDTO(String name, String bornOn, String deliveredOn) {
super();
this.name = name;
this.bornOn = bornOn;
this.deliveredOn = deliveredOn;
}
public String getDisplayName() {
return name;
}
public String getDateOfBirth() {
return bornOn;
}
public String getDeliveryDate() {
return deliveredOn;
}
public String toCodeString() {
final StringBuilder sb = new StringBuilder();
sb.append("new AnimalDTO(\"");
sb.append(this.getDisplayName()).append("\",");
sb.append("\"").append(this.getDateOfBirth()).append("\",");
sb.append("\"").append(this.getDeliveryDate());
sb.append(");");
return sb.toString();
}
}
}
@mikaelgrev
Copy link

Since Swing has such a bad spec on these things and what to do when width and height are connected these kinds of bugs are just fix one and get two more. If you find a simple fix where it is clear that MigLayout breaks the contract, please submit a pull request and I'll look. But otherwise the effort/time is just too large for trying to circumvent Swing's shortcomings. Or just do a local fix for your version, which might be easiest.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment