I have a Canvas that contains a Label. I want to set font size of this label according to the Canvas size.
How we can do this?
EDIT: "contains" means, Canvas and Label bounds are same.
EDIT2: I have this for Swing, but I couldn't convert it to SWT;
Font labelFont = label.getFont();
String labelText = label.getText();
int stringWidth = label.getFontMetrics(labelFont).stringWidth(labelText);
int componentWidth = label.getWidth();
double widthRatio = (double)componentWidth / (double)stringWidth;
int newFontSize = (int)(labelFont.getSize() * widthRatio);
int componentHeight = label.getHeight();
int fontSizeToUse = Math.min(newFontSize, componentHeight);
EDIT3:
This is my font size calculator class for label
public class FitFontSize {
public static int Calculate(Label l) {
Point size = l.getSize();
FontData[] fontData = l.getFont().getFontData();
GC gc = new GC(l);
int stringWidth = gc.stringExtent(l.getText()).x;
double widthRatio = (double) size.x / (double) stringWidth;
int newFontSize = (int) (fontData[0].getHeight() * widthRatio);
int componentHeight = size.y;
System.out.println(newFontSize + " " + componentHeight);
return Math.min(newFontSize, componentHeight);
}
}
and this is my Label at the top of the window. I want its font size according the volume of Layer size.
Label l = new Label(shell, SWT.NONE);
l.setText("TITLE HERE");
l.setBounds(0,0,shell.getClientArea().width, (shell.getClientArea().height * 10 )/ 100);
l.setFont(new Font(display, "Tahoma", 16,SWT.BOLD));
l.setFont(new Font(display, "Tahoma", FitFontSize.Calculate(l),SWT.BOLD));
I have just ported the code above.
You can get the extent (length) of a String in SWT with the method GC.stringExtent(); and you need the Class FontData to get the font height and font width of the Label.
Label label = new Label(parent, SWT.BORDER);
label.setSize(50, 30);
label.setText("String");
// Get the label size and the font data
Point size = label.getSize();
FontData[] fontData = label.getFont().getFontData();
GC gc = new GC(label);
int stringWidth = gc.stringExtent(label.getText()).x;
// Note: In original answer was ...size.x + (double)..., must be / not +
double widthRatio = (double) size.x / (double) stringWidth;
int newFontSize = (int) (fontData[0].getHeight() * widthRatio);
int componentHeight = size.y;
int fontsizeToUse = Math.min(newFontSize, componentHeight);
// set the font
fontData[0].setHeight(fontsizeToUse);
label.setFont(new Font(Display.getCurrent(), fontData[0]));
gc.dispose();
Sources:
Stackoverflow: Change just the font size in SWT
Eclipse API: GC
Related
I use drawString by Font1, suppose deriveFont is 20f.
final int width = fontMetrics.stringWidth(text);
final int height = fontMetrics.getHeight();
BufferedImage rendered = new BufferedImage(
width, height, BufferedImage.TYPE_INT_ARGB
);
System.out.println("render:" + width + "," + height);
final Graphics2D gOfRendered = (Graphics2D) rendered.getGraphics();
gOfRendered.setRenderingHints(getRenderingHints());
gOfRendered.setColor(fontColor);
gOfRendered.setFont(fontMetrics.getFont());
gOfRendered.drawString(
text, 0, height - fontMetrics.getMaxDescent() - fontMetrics.getLeading()
);
result:
But when I scale font size(scale=4 result maybe normal,scale=8 will cause error result):
final Font font = (wordFrequency.hasFont() ? wordFrequency.getFont() : kumoFont).getFont().deriveFont(fontHeight * 1.0f);
final Font font2 = (wordFrequency.hasFont() ? wordFrequency.getFont() : kumoFont).getFont().deriveFont(fontHeight * scale * 1.0f);
final FontMetrics fontMetrics = graphics.getFontMetrics(font);
final FontMetrics fontMetrics2 = graphics.getFontMetrics(font2);
and render again:
final int width = fontMetrics2.stringWidth(text);
final int height = fontMetrics2.getHeight();
BufferedImage rendered = new BufferedImage(
width, height, BufferedImage.TYPE_INT_ARGB
);
final Graphics2D gOfRendered = (Graphics2D) rendered.getGraphics();
// set the rendering hint here to ensure the font metrics are correct
gOfRendered.setRenderingHints(getRenderingHints());
gOfRendered.setColor(fontColor);
gOfRendered.setFont(fontMetrics2.getFont());
gOfRendered.drawString(
text, 0, height - fontMetrics2.getMaxDescent() - fontMetrics2.getLeading()
);
Error result(scale=8):
I find final int width = fontMetrics2.stringWidth(text); is not 8 times the font width,the Numbers are very different,How to fix it?Thank you!
I wrote a little Java program for a friend of mine, we have the same resolution ( 1920 * 1080 ), but his Screen in general is smaller than mine. To solve the problem I gave the GUI elements percentual coordinates, which works perfectly until I use fonts. The Font will be the same size, like mine which is like the code expects. The Bounds for a JButton for example says where to start where to end, but a font measured in points, so each inch has 72 points, a Font with 30 will always be half an inch. (Compare to the Images)
How can I fix this, I found nothing that could solve the problem in my eyes?
Image Before:
https://ibb.co/HXf0pt4
Image After:
https://ibb.co/1sbKyts
public class DrawMenu extends JLabel{
private static final long serialVersionUID = 1L;
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int sw = (int) Toolkit.getDefaultToolkit().getScreenSize().getWidth();
int sh = (int) Toolkit.getDefaultToolkit().getScreenSize().getHeight();
g.setFont(new Font("TimesRoman", Font.PLAIN, (int)Math.round(sw * 0.0078)));
g.drawString("Termine die nächsten 0 bis 7 Tage", (int)Math.round(sw * 0.026), (int)Math.round(sh * 0.176));
g.drawString("Termine die nächsten 8 bis 14 Tage", (int)Math.round(sw * 0.182), (int)Math.round(sh * 0.176));
repaint();
}
}
public class Gui {
static JFrame jfCounter, jfMenu, jfTask;
static DrawCounter drawc;
static DrawMenu drawm;
static DrawTask drawt;
static JButton kEnde, kNC, kA, kL, kEsc1, kEsc2, kEsc3, kEsc4, kEsc5, kLG, kLB, kAS, kEnter, kJFsw1, kJFsw2, kJFsw3,
kJFsw4, ko[] = new JButton[6], kSettings, ktw, ktla, ktle, ktlb, ktnt;
static JTextArea taAusgabe, taAusgabedw, taAusgabenw, taze, tabe, tati;
static JFormattedTextField nfTag, nfMonat, nfJahr, nfTagA, nfMonatA, nfJahrA;
static JTextField tfAnlass, tfkLBestimmt, tfAnlassA, tfAnlassAS, tfKonsole, tfKonsoleT, tfsettings[] = new JTextField[12], tftw,
tftis, tftlbs, tftnct, tftnci;
public Gui() {
int sw = (int) Toolkit.getDefaultToolkit().getScreenSize().getWidth();
int sh = (int) Toolkit.getDefaultToolkit().getScreenSize().getHeight();
System.out.println(sw + " " + sh);
// JFrame Settings
jfCounter = new JFrame();
jfCounter.setSize(sw, sh);
jfCounter.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jfCounter.setLocationRelativeTo(null);
jfCounter.setExtendedState(JFrame.MAXIMIZED_BOTH);
jfCounter.setTitle("Tageszähler");
jfMenu = new JFrame();
jfMenu.setSize(sw, sh);
jfMenu.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jfMenu.setLocationRelativeTo(null);
jfMenu.setExtendedState(JFrame.MAXIMIZED_BOTH);
jfMenu.setTitle("Menü");
jfTask = new JFrame();
jfTask.setSize(sw, sh);
jfTask.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jfTask.setLocationRelativeTo(null);
jfTask.setExtendedState(JFrame.MAXIMIZED_BOTH);
jfTask.setTitle("Task");
// JButtons
Border bor = BorderFactory.createLineBorder(Color.BLACK, 1);
Border boresc = BorderFactory.createLineBorder(Color.RED, 3);
kEnde = new JButton("Ende");
kEnde.addActionListener(new ActionHandler());
kEnde.setBounds((int) Math.round(sw * 0.026), (int) Math.round(sh * 0.509), (int) Math.round(sw * 0.195),
(int) Math.round(sh * 0.028));
kEnde.setBorder(bor);
jfCounter.add(kEnde);
kNC = new JButton("Neuer Counter");
kNC.addActionListener(new ActionHandler());
kNC.setBounds((int) Math.round(sw * 0.026), (int) Math.round(sh * 0.028), (int) Math.round(sw * 0.078),
(int) Math.round(sh * 0.028));
kNC.setBorder(bor);
jfCounter.add(kNC);
// JLabel / Draw
drawc = new DrawCounter();
drawc.setBounds(0, 0, sw, sh);
drawc.setVisible(true);
jfCounter.add(drawc);
drawm = new DrawMenu();
drawm.setBounds(0, 0, sw, sh);
drawm.setVisible(true);
jfMenu.add(drawm);
drawt = new DrawTask();
drawt.setBounds(0, 0, sw, sh);
drawt.setVisible(true);
jfTask.add(drawt);
// JFrame Final Visible
Gui.getJfMenu().setVisible(true);
}
I have a txt file with nrows, ncols etc and ex elevation values as numbers which we are supposed to make a map image of.
I have code (that works) but my problem is that the pixels are exactly one pixel big each, they actually have a cellsize also that already is defined(10m). When the code runs I get the smallest greyscale map ever, I want it to be atleast 10x10 cm big imageicon so I can se what's going on but I don't know where to set it please help. Already searched for ways to resize etc but noone really fit me, what about a setpixels solution?
public void mapColor()
{
int height = nRows; int width = nCols;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
WritableRaster raster = image.getRaster();
for (int i = 0; i < nRows; i++) {
for (int j = 0; j < nCols; j++) {
double value = values[i][j];
int[] color = new int[3];
int colValue = getColorValue(value); //In this case Green to Red strength
int percentage = ((100*colValue)/255);
int R; int G; int B = 0;
//Formula: Red= 255*percentage /100 G= (255*(100-percentage))/100
R = (255*percentage)/100; G=(255*(100-percentage))/100;
R = Math.round(R); G= Math.round(G);
color[0]= R; color[1] = G; color[2] = B; //100% will be bright red and 50% yellow
raster.setPixel(j, i, color);
//System.out.println("Value " + value + " Red is " + R + " Green is " + G);
}
}
JFrame jf = new JFrame();
JLabel jl = new JLabel();
ImageIcon ii = new ImageIcon(image);
jl.setIcon(ii);
jf.add(jl);
jf.setSize(200, 200);
jf.setVisible(true);
}
This returns an image that is 2x2mm big, values is a double array with all elevation data. It's my first java course ever I want easy solutions.
The most simple solution would be to use the getScaledInstance method
and use the resulting image to create the ImageIcon:
Image scaledImage = image.getScaledInstance(200 * nRows, 200 * nCols, Image.SCALE_DEFAULT);
ImageIcon ii = new ImageIcon(scaledImage);
im working on a project where i am drawing an image on a JPanel and then putting that panel inside a JScrollPane. The panel itself will vary in size sometimes being smaller than the screen, sometimes larger. When it is larger the scrollpane doesn't seem to have any scroll bars appearing. Im sure im messing something up that is simple but i can't seem to figure it out.
Any help would be greatly appreaciated.
public void createGI(theTicket[] ticketArray){
JFrame ticketReportFrame = new JFrame();
ticketReportFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel ticketReport = new drawTurnoverReport(ticketArray , notes, tapes, turnover);
ticketReport.setBackground(Color.WHITE);
ticketReport.setLayout(new BorderLayout());
JScrollPane ticketReportHolder = new JScrollPane(ticketReport);
ticketReportFrame.setExtendedState(Frame.MAXIMIZED_BOTH);
ticketReportFrame.pack();
ticketReportHolder.setWheelScrollingEnabled(true);
ticketReportFrame.add(ticketReportHolder);
ticketReportFrame.setVisible(true);
ticketReportFrame.setResizable(false);
}
this is just a small portion of drawTurnoverReport to try and help show what i am doing.
public class drawTurnoverReport extends JPanel{
public drawTurnoverReport(theTicket[] tickets, String[] n, String[] t, String[] to){
ticArray = tickets;
notes = n;
tapes = t;
turnover = to;
formalDate = mt.formalDate;
}
#Override
protected void paintComponent(Graphics g){
super.paintComponent( g );
Graphics2D g2 = (Graphics2D) g;
//set fonts
Font tahomaB = new Font("tahoma", Font.BOLD, 15);
Font tahomaP = new Font("tahoma", Font.PLAIN, 15);
//draw heading
g2.setColor(Color.BLACK);
g2.setFont(tahomaB);
Rectangle2D rec = g2.getFontMetrics().getStringBounds("Turnover / Activity Log", g2);
int stringW = (int) rec.getWidth();
int prevStringH = (int) rec.getHeight();
g2.drawString("Turnover / Activity Log", x-(stringW / 2) , 50);
g2.setFont(tahomaP);
rec = g2.getFontMetrics().getStringBounds("Date: " + formalDate, g2);
stringW = (int) rec.getWidth();
verticalPlace = 50 + prevStringH;
g2.drawString("Date: " + formalDate, x-(stringW / 2) , verticalPlace);
prevStringH = (int) rec.getHeight();
verticalPlace += prevStringH;
g2.setFont(tahomaB);
rec = g2.getFontMetrics().getStringBounds("Service Manager Tickets", g2);
stringW = (int) rec.getWidth();
g2.drawString("Service Manager Tickets", x-(stringW / 2) , verticalPlace);
verticalPlace +=2;
g2.drawLine(((int)rec.getMinX()+ x)-(stringW / 2 +2), verticalPlace,
((int)rec.getMaxX()+x)-(stringW / 2), verticalPlace);
verticalPlace += 40;
//draw table headers
verticalUnderHeader = verticalPlace;
g2.drawLine(50, verticalPlace, w-50, verticalPlace);
rec = g2.getFontMetrics().getStringBounds(ticArray[0].getTicketNum(), g2);
stringW = (int) rec.getWidth();
rec = g2.getFontMetrics().getStringBounds("Ticket #", g2);
temp = (int) rec.getWidth();
g2.drawString("Ticket #", ((stringW+65+50)/2-(temp/2)), verticalPlace+17);
horzPlace = stringW + 65;
CNCxA = horzPlace;
rec = g2.getFontMetrics().getStringBounds("Customer Name", g2);
stringW = (int) rec.getWidth();
widthCNC = (horzPlace + stringW + 30)-horzPlace;
g2.drawString("Customer Name", horzPlace + 15, verticalPlace+17);
horzPlace = horzPlace + stringW + 30;
CNCxB = horzPlace;
temp = w-horzPlace+30;
DCx = temp;
widthDC = temp - horzPlace;
rec = g2.getFontMetrics().getStringBounds("Description", g2);
stringW = (int) rec.getWidth();
g2.drawString("Description", (horzPlace+temp)/2-(stringW/2), verticalPlace+17);
rec = g2.getFontMetrics().getStringBounds("Status", g2);
stringW = (int) rec.getWidth();
g2.drawString("Status", (temp+(w-50))/2-(stringW/2), verticalPlace+17);
verticalPlace += 20;
g2.drawLine(50, verticalPlace, w-50, verticalPlace);
verticalPlaceTemp = verticalPlace + 20;
}
}
From the sounds of things, the drawTurnoverReport component isn't providing enough size hint information to the scroll pane.
JScrollPane will use the components preferredSize to determine if it needs to display scroll bars or not.
Ensure you are overriding the getPreferredSize method and return an appropriate size of the component.
For example:
Add an Background image to a Panel
Having images as background of JPanel
This assumes that you are performing some kind of custom painting and not using something like JLabel to render the image, which would then suggest you have a layout issue somewhere...but without the source for drawTurnoverReport, it's impossible to know...
is it possible to print part of the screen around the mouse?
I try with :
Toolkit tool = Toolkit.getDefaultToolkit();
Dimension d = tool.getScreenSize();
Rectangle rect = new Rectangle(d);
Robot robot = new Robot();
File f = new File("screenshot.jpg");
BufferedImage img = robot.createScreenCapture(rect);
ImageIO.write(img,"jpeg",f);
but it prints all screen, i can see that i can set the size of rectangle but i don't see how can i center rectangle so that it be around mouse.
public static BufferedImage printScrAroundCursor(int width, int height)
{
Toolkit tool = Toolkit.getDefaultToolkit();
Robot robot = new Robot();
PointerInfo a = MouseInfo.getPointerInfo();
Point b = a.getLocation();
int x = (int) b.getX();
int y = (int) b.getY();
int topLeftX = Math.max(0, x - (width / 2));
int topLeftY = Math.max(0, y - (height / 2));
if (topLeftX + width > tool.getScreenSize().getWidth())
width = tool.getScreenSize().getWidth() - topLeftX;
if (topLeftX + width > tool.getScreenSize().getHeight())
width = tool.getScreenSize().getHeight() - topLeftY;
return robot.createScreenCapture(new Rectangle(topLeftX , topLeftY , width, height));
}
You can use MouseInfo to get the mouse's location. From there, it's simple midpoint math:
int width = ...;
int height = ...;
Point m = MouseInfo.getPointerInfo().getLocation();
Rectangle rect = new Rectangle(m.x - width / 2, m.y - height / 2, width, height);
Robot robot = new Robot();
File f = new File("screenshot.jpg");
BufferedImage img = robot.createScreenCapture(rect);
ImageIO.write(img, "jpeg" ,f);
You will probably encounter strange results if the mouse is too close to the edge of the screen, but without more information, this special behavior is up to you to define how you wish for it to be.
Point mousePos = MouseInfo.getPointerInfo().getLocation();
int width = 300;
int height = 300;
Point origin = new Point(mousePos.getX() - width / 2, mousePos.getY() - height / 2);
Rectangle rect = new Rectangle(origin.getX(), origin.getY(), width, height);
BufferedImage img = robot.createScreenCapture(rect);