在我的应用程序中,我的标签字体大小超过200.此标签包含大的上下(不规则)间隙。我该如何删除它?
这是我的代码:
package Core;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public class LabelDemo extends JPanel {
public LabelDemo() {
super(new GridBagLayout());
JLabel label2;
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
// Create the other labels.
label2 = new JLabel("Text-Only Label");
label2.setBorder(BorderFactory.createTitledBorder("aaaaaaaa"));
label2.setFont(new Font("Verdana", Font.PLAIN, (int) 220));
// label2.setBorder(new EmptyBorder(-50, 0, 0, 0));
// Add the labels.
add(label2, c);
}
/**
* Create the GUI and show it. For thread safety, this method should be invoked from the event dispatch thread.
*/
private static void createAndShowGUI() {
// Create and set up the window.
JFrame frame = new JFrame("LabelDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Add content to the window.
frame.add(new LabelDemo());
// Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
// Schedule a job for the event dispatch thread:
// creating and showing this application's GUI.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// Turn off metal's use of bold fonts
UIManager.put("swing.boldMetal", Boolean.FALSE);
createAndShowGUI();
}
});
}
}
我也尝试了我的上一篇文章:How to change gap in swing label并尝试使用插图,但这在linux和windows中看起来不同
有没有更好的方法来消除这种差距?
答案 0 :(得分:9)
JDigit
可能会给你一些想法:
覆盖paintComponent()
以对高分辨率BufferedImage
进行下采样并控制几何体。
它使用setBorderPainted(false)
设置borderPainted
属性。
它使用FocusHandler
进行自定义突出显示。
附录:如上所述here,根本问题是字体的前导,在FontMetrics
中定义为包含在字体的高度中。正如@Guillaume Polet的评论中所建议的那样,您可以在自己的JComponent
中随意呈现文本。讨论here的TextLayout
可用于计算边界,如下所示。
优点:
对展示位置的绝对控制。
基于TexteLayout
的{{1}}边界的几何。
缺点:
没有FontMetrics
支持。
没有HTML支持。
请注意,Icon
作者“建议您将该组件放在JComponent
中,并在JPanel
上设置边框。”
JPanel
答案 1 :(得分:3)
执行此操作的“正确方法”是扩展“BasicLabelUI”并覆盖“protected String layoutCL()”方法。这是负责在标签内布局所有内容的方法,并在调用JLabel的“getPreferredSize()”时调用。因此,此方法确定组件的高度。
如果向下深入,你会看到高度由SwingUtilities:1021类中的以下行确定(由layoutCL使用):
textR.height = fm.getHeight();
因此标签不会导致空格,字体是。标签符合FontMetrics对象所说的是该大小字体的最大高度。
最简单的方法可能是作弊;强制进行大小计算以执行不应该执行的操作。下面是您可以试验的自定义LabelUI组件的示例。例如,如果强制变量'dy'为'-40',则文本将位于顶部。如果你想让更耐用的东西你可以检查标签字符串中的所有leters,测量它们的最大高度并在layoutCL方法中使用它。但那显然更有效。
package Core;
import sun.swing.SwingUtilities2;
import javax.swing.*;
import javax.swing.plaf.LabelUI;
import javax.swing.plaf.basic.BasicLabelUI;
import javax.swing.text.View;
import java.awt.*;
public class LabelDemo extends JPanel {
public LabelDemo() {
super(new GridBagLayout());
JLabel label2;
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
// Create the other labels.
label2 = new JLabel("Text-Only Label");
label2.setVerticalAlignment(SwingUtilities.TOP);
label2.setVerticalTextPosition(SwingUtilities.TOP);
label2.setUI(SkinnyLabelUI.createUI(label2));
label2.setBorder(BorderFactory.createTitledBorder("aaaaaaaa"));
label2.setFont(new Font("Verdana", Font.PLAIN, (int) 220));
// label2.setBorder(new EmptyBorder(-50, 0, 0, 0));
// Add the labels.
add(label2, c);
}
/**
* Create the GUI and show it. For thread safety, this method should be
* invoked from the event dispatch thread.
*/
private static void createAndShowGUI() {
// Create and set up the window.
JFrame frame = new JFrame("LabelDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Add content to the window.
frame.add(new LabelDemo());
// Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
// Schedule a job for the event dispatch thread:
// creating and showing this application's GUI.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// Turn off metal's use of bold fonts
UIManager.put("swing.boldMetal", Boolean.FALSE);
createAndShowGUI();
}
});
}
private static class SkinnyLabelUI extends BasicLabelUI {
private static final SkinnyLabelUI labelUI = new SkinnyLabelUI();
public static LabelUI createUI(JComponent c) {
return labelUI;
}
protected String layoutCL(
JLabel label,
FontMetrics fm,
String text,
Icon icon,
Rectangle viewR,
Rectangle iconR,
Rectangle textR) {
int verticalAlignment = label.getVerticalAlignment();
int horizontalAlignment = label.getHorizontalAlignment();
int verticalTextPosition = label.getVerticalTextPosition();
int horizontalTextPosition = label.getHorizontalTextPosition();
if (icon != null) {
iconR.width = icon.getIconWidth();
iconR.height = icon.getIconHeight();
} else {
iconR.width = iconR.height = 0;
}
/* Initialize the text bounds rectangle textR. If a null
* or and empty String was specified we substitute "" here
* and use 0,0,0,0 for textR.
*/
boolean textIsEmpty = (text == null) || text.equals("");
int lsb = 0;
int rsb = 0;
/* Unless both text and icon are non-null, we effectively ignore
* the value of textIconGap.
*/
int gap;
View v;
if (textIsEmpty) {
textR.width = textR.height = 0;
text = "";
gap = 0;
} else {
int availTextWidth;
gap = (icon == null) ? 0 : label.getIconTextGap();
if (horizontalTextPosition == SwingUtilities.CENTER) {
availTextWidth = viewR.width;
} else {
availTextWidth = viewR.width - (iconR.width + gap);
}
v = (label != null) ? (View) label.getClientProperty("html") : null;
if (v != null) {
textR.width = Math.min(availTextWidth,
(int) v.getPreferredSpan(View.X_AXIS));
textR.height = (int) v.getPreferredSpan(View.Y_AXIS);
} else {
textR.width = SwingUtilities2.stringWidth(label, fm, text);
lsb = SwingUtilities2.getLeftSideBearing(label, fm, text);
if (lsb < 0) {
// If lsb is negative, add it to the width and later
// adjust the x location. This gives more space than is
// actually needed.
// This is done like this for two reasons:
// 1. If we set the width to the actual bounds all
// callers would have to account for negative lsb
// (pref size calculations ONLY look at width of
// textR)
// 2. You can do a drawString at the returned location
// and the text won't be clipped.
textR.width -= lsb;
}
if (textR.width > availTextWidth) {
text = SwingUtilities2.clipString(label, fm, text,
availTextWidth);
textR.width = SwingUtilities2.stringWidth(label, fm, text);
}
textR.height = fm.getHeight();
System.out.println("font height: " + textR.height);
}
}
/* Compute textR.x,y given the verticalTextPosition and
* horizontalTextPosition properties
*/
if (verticalTextPosition == SwingUtilities.TOP) {
if (horizontalTextPosition != SwingUtilities.CENTER) {
textR.y = 0;
} else {
textR.y = -(textR.height + gap);
}
} else if (verticalTextPosition == SwingUtilities.CENTER) {
textR.y = (iconR.height / 2) - (textR.height / 2);
} else { // (verticalTextPosition == BOTTOM)
if (horizontalTextPosition != SwingUtilities.CENTER) {
textR.y = iconR.height - textR.height;
} else {
textR.y = (iconR.height + gap);
}
}
if (horizontalTextPosition == SwingUtilities.LEFT) {
textR.x = -(textR.width + gap);
} else if (horizontalTextPosition == SwingUtilities.CENTER) {
textR.x = (iconR.width / 2) - (textR.width / 2);
} else { // (horizontalTextPosition == RIGHT)
textR.x = (iconR.width + gap);
}
// WARNING: DefaultTreeCellEditor uses a shortened version of
// this algorithm to position it's Icon. If you change how this
// is calculated, be sure and update DefaultTreeCellEditor too.
/* labelR is the rectangle that contains iconR and textR.
* Move it to its proper position given the labelAlignment
* properties.
*
* To avoid actually allocating a Rectangle, Rectangle.union
* has been inlined below.
*/
int labelR_x = Math.min(iconR.x, textR.x);
int labelR_width = Math.max(iconR.x + iconR.width,
textR.x + textR.width) - labelR_x;
int labelR_y = Math.min(iconR.y, textR.y);
int labelR_height = Math.max(iconR.y + iconR.height,
textR.y + textR.height) - labelR_y;
int dx, dy;
if (verticalAlignment == SwingUtilities.TOP) {
dy = viewR.y - labelR_y;
} else if (verticalAlignment == SwingUtilities.CENTER) {
dy = (viewR.y + (viewR.height / 2)) - (labelR_y + (labelR_height / 2));
} else { // (verticalAlignment == BOTTOM)
dy = (viewR.y + viewR.height) - (labelR_y + labelR_height);
}
if (horizontalAlignment == SwingUtilities.LEFT) {
dx = viewR.x - labelR_x;
} else if (horizontalAlignment == SwingUtilities.RIGHT) {
dx = (viewR.x + viewR.width) - (labelR_x + labelR_width);
} else { // (horizontalAlignment == CENTER)
dx = (viewR.x + (viewR.width / 2))
- (labelR_x + (labelR_width / 2));
}
/* Translate textR and glypyR by dx,dy.
*/
textR.x += dx;
textR.y += dy;
iconR.x += dx;
iconR.y += dy;
if (lsb < 0) {
// lsb is negative. Shift the x location so that the text is
// visually drawn at the right location.
textR.x -= lsb;
textR.width += lsb;
}
if (rsb > 0) {
textR.width -= rsb;
}
return text;
}
}
}
答案 2 :(得分:0)
更改边框偏移可能会有所帮助:
int OFFSET_TOP=50,OFFSET_BOTTOM=50;
label.setBorder(new TitledBorder(TITLE){
@Override
public Insets getBorderInsets(Component c, Insets insets){
return new Insets(insets.top - OFFSET_TOP, insets.left, insets.bottom - OFFSET_BOTTOM, insets.right);
}
});