在Java中,有Graphics2D.fillRect(x, y, width, height)函数。在我的程序中,我正在寻找类似但完全相反的东西。
我需要填充屏幕上的所有内容,除了这个特定的x、y、宽度、高度,有点像反填充矩形。是否有我忽略的内置功能,或者您能给我指出创建该功能的正确方向吗?
不是必需的,但如果它可以与其他 Java 2D 形状一起使用,那就太好了。
我尝试将文本渲染到 BufferedImage,效果非常好,但我无法渲染任何非 ASCII 字符(至少据我所知)。我所能找到的只是因为字体的原因,所以我下载了谷歌的“Noto”字体,它似乎支持几乎所有脚本,但我仍然得到了这些框。
\n\n我什至不想渲染一些特别异国情调的东西。仅德语变音符号和升号 s (\xc3\x84\xc3\xa4 \xc3\x96\xc3\xb6 \xc3\x9c\xc3\xbc \xc3\x9f)。
\n\n我创建这样的字体
\n\nFont font = Font.createFont(Font.TRUETYPE_FONT, new FileInputStream("NotoSans-Regular.ttf")).deriveFont(12f);\nRun Code Online (Sandbox Code Playgroud)\n\n并像这样渲染整个事情
\n\nGraphics2D g2 = image.createGraphics();\ng2.setFont(font);\ng2.setColor(Color.white);\ng2.drawString(string, 0, g2.getFontMetrics().getAscent());\ng2.dispose();\nRun Code Online (Sandbox Code Playgroud)\n\n它适用于 ASCII。
\n\n谷歌要么引导我找到非常简单的教程(这实际上是我目前得到的代码),要么说问题出在字体上,但事实并非如此,因为它在编辑器中运行得很好。
\n\n谢谢
\n\n编辑1:这是我的完整代码
\n\nimport javax.imageio.ImageIO;\nimport java.awt.*;\nimport java.awt.font.FontRenderContext;\nimport java.awt.geom.Rectangle2D;\nimport java.awt.image.BufferedImage;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.IOException;\n\npublic class Test {\n public static void main(String[] args) throws IOException, FontFormatException {\n String string = "\xc3\x84\xc3\xa4\xc3\x96\xc3\xb6\xc3\x9c\xc3\xbc\xc3\x9f";\n BufferedImage image;\n\n Font font = Font.createFont(Font.TRUETYPE_FONT, new FileInputStream("NotoSans-Regular.ttf")).deriveFont(50f);\n Rectangle2D rec = font.getStringBounds(string, new FontRenderContext(null, false, …Run Code Online (Sandbox Code Playgroud) 我想知道如何在android中制作这种动画(在Battery Doctor应用程序中也是如此)。

我找到了一种方法,使用两个不透明度为 50% 的绿色图像,一个在另一个后面,另一个在前面,以隐藏不需要的内容(圆圈),我使用下面的代码通过 XML 对第一个绿色图像进行动画处理
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:duration="1850"
android:fromDegrees="-4"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:interpolator="@android:anim/linear_interpolator"
android:toDegrees="4" />
<translate
android:fromXDelta="0"
android:toXDelta="0"
android:fromYDelta="0"
android:toYDelta="1"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:interpolator="@android:anim/linear_interpolator"
android:duration="1500" />
</set>
Run Code Online (Sandbox Code Playgroud)
第二个绿色的使用这个:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:duration="1800"
android:fromDegrees="-1"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:interpolator="@android:anim/linear_interpolator"
android:toDegrees="1" />
<translate
android:fromXDelta="80"
android:toXDelta="-4"
android:fromYDelta="-1"
android:toYDelta="1"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:interpolator="@android:anim/linear_interpolator"
android:duration="1500" />
</set>
Run Code Online (Sandbox Code Playgroud)
但是如何以编程方式创建视图?我想从代码动态设置级别。例如 myView.setLevel(45);
我读过很多关于绘制 Graphics2D 组件和添加到 JPanel/JFrame 的教程,但我找不到如何简单地将多个这些组件添加到一个 JPanel 中。我下面的代码只添加了 1 个组件(行),我找不到为什么不能添加更多组件。
我究竟做错了什么?

期望的行为:应该有 3 条红线。
我的整个代码:
package Examples;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Example1 extends JFrame {
private final JPanel panel;
public Example1() {
// jpanel with graphics
panel = new JPanel();
panel.setPreferredSize(new Dimension(200, 200));
panel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
panel.setBackground(Color.WHITE);
add(panel);
// adding lines to jpanel
AddMyLine(); // 1st: this works well
AddMyLine(); // 2nd: …Run Code Online (Sandbox Code Playgroud) 在Java的Graphics2D类中,它有一个transform方法。
public abstract void transform(AffineTransform Tx)
Run Code Online (Sandbox Code Playgroud)
这是根据文档的描述:
根据后指定先应用的规则与此 Graphics2D 中的 Transform 组合一个 AffineTransform 对象。如果当前Transform是Cx,则与Tx合成的结果是新的Transform Cx'。Cx' 成为该 Graphics2D 的当前变换。通过更新的变换 Cx' 变换点 p 相当于先通过 Tx 变换 p,然后通过原始变换 Cx 变换结果。换句话说,Cx'(p) = Cx(Tx(p))。如有必要,会制作 Tx 的副本,因此对 Tx 的进一步修改不会影响渲染。
我读了好几遍了,但还是不明白它的作用。我也尝试过寻找其他来源,但关于 g2d 的转换方法的内容并不多。
所以我的问题是:转换到底做什么?我们什么时候使用它?
如果有人能以简化的方式解释它,那就太好了。
drawPolyline()与遍历每一行并drawLine()在类中调用相比,调用有什么好处吗Graphics2D?
例如:
graphics2d.drawPolyline(xPoints, yPoints, nPoints);
相对:
for (MyBean line : myBeans) {
graphics2d.drawLine(line.getX1Point(), line.getY1Point(), line.getX2Point(), line.getY2Point());
}
Run Code Online (Sandbox Code Playgroud)
第一个方法是第二个方法的便捷方法吗?
对 AWT 来说还很陌生。(我意识到第一个可能更简洁。)
编辑:我呼吁BufferedImage.createGraphics()实施Graphics2D.
我试图在框架的右下四分之一处绘制一个半径为60的圆,以及在框架的上半部分中心的半径为50的正方形.
框架尺寸为300 x 300.我一直这样做.
import java.awt.*;
import javax.swing.*;
import java.awt.geom.*;
public class Test {
public static void main ( String[] args){
JFrameTest5 frame = new JFrameTest5();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setTitle("Test");
}
}
class JFrameTest5 extends JFrame {
public JFrameTest5()
{
setLocation(0,0);
setSize(300,300);
PanelTest1 panel = new PanelTest1();
add(panel);
}
}
class PanelTest1 extends JPanel
{
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D)g;
Ellipse2D circle = new Ellipse2D.Double(250, 225, 120,120);
g2.draw(circle);
Rectangle2D rect = new Rectangle2D.Double(75,0,100,100);
g2.draw(rect);
}
}
Run Code Online (Sandbox Code Playgroud)
问题是圆圈和矩形似乎不对,有没有其他方法来设置确切的半径?
我想找到触摸或包含给定有限线段部分的所有网格图块.网格是2d规则网格,因此我可以从图块位置(行,列)推导出任何图块的中心,反之亦然我可以从给定的浮点坐标计算图块位置,具有两个快速整数除法.瓦片是二次的,例如0.25x0.25,其中0.25被定义为瓦片宽度.现在我需要确定给定线段触摸的所有图块(浮点数中给出的两个2d点定义一个线段).我目前的方法是将片段分割成等距点,其距离是拼贴宽度的一半(向shannon的问候).我收集包含给定点的所有瓷砖并删除重复的瓷砖.
编辑:正如Patricia所指出的那样,我目前的方法并没有产生完整的图块集,因为不会包含只触及线条非常小部分的图块.这对我来说是可以接受的,因为在我看来,速度比准确性更重要,但应该注意到.
为了使它更清晰:我想要图像中的所有红色瓷砖,但如果我获得速度,我可以保留例如玫瑰色的瓷砖.

我花了几天时间试图让Graphics2D类在我的代码中工作.我以这样的方式构造它,当注册click事件时,对repaint的调用完成,但是当它到达调用repaint()的阶段时,它只产生一个nullpointer异常.
它在调试时都按预期工作,而不是在paintComponent方法中调用,但是当尝试使用paintComponent和repaint()正确调用代码以允许Graphics2D类显示每个点的行时,它不起作用.
我已经包含了我的代码部分,我很难开始工作.任何帮助都将非常感激.先感谢您.
下面是包含我的mouseListener的GUI类.
public class GUI extends JPanel implements MouseListener {
private JLabel label;
public BufferedImage getImg() {
return img;
}
public void mouseClicked(java.awt.event.MouseEvent e) {
// TODO Auto-generated method stub
label = new JLabel();
//set point equal to the location of the mouse click on the image label
Point b = e.getPoint();
//place we are going to print the dots
segmentation.x = b.x; //gets the x coordinate
segmentation.y = b.y; //gets the y coordinate
System.out.println("x = " + …Run Code Online (Sandbox Code Playgroud) 我试图让一个JPanel透明,但我不能让它工作.是否有可能做到这一点?
import java.awt.*;
import javax.swing.*;
public class ClearPanel extends JPanel{
public static void main(String[] args) {
ClearPanel c = new ClearPanel();
c.setPreferredSize(new Dimension(200, 200));
c.setOpaque(false);
JPanel backPanel = new JPanel();
backPanel.setBackground(Color.CYAN);
backPanel.add(c);
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setContentPane(backPanel);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.fillOval(0, 0, 200, 200);
g.clearRect(45, 45, 50, 50);
Graphics2D g2 = (Graphics2D) g;
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.0f));
g2.fillRect(75, 75, 50, 50);
}
}
Run Code Online (Sandbox Code Playgroud)
椭圆形应该是不透明的,但矩形我想要透明.透明,我的意思是我应该能够看到ClearPanel背后的面板.
关于MadProgrammer的回答,有没有办法让灰色的盒子在区域之外的地方绘制,但是在该区域内保持透明?
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); …Run Code Online (Sandbox Code Playgroud) graphics2d ×10
java ×9
swing ×4
awt ×2
jpanel ×2
algorithm ×1
android ×1
animation ×1
fonts ×1
geometry ×1
grid ×1
jcomponent ×1
jframe ×1
opengl-es ×1
performance ×1
transform ×1
transparency ×1
unicode ×1