tôi đã nhìn vào vấn đề này và không thể nhìn thấy làm thế nào để làm điều này trong một một cuộc gọi đến các lớp hệ thống.
Graphics2D là một phiên bản trừu tượng, được triển khai dưới dạng SunGraphics2D. Mã nguồn có sẵn tại ví dụ docjar và vì vậy chúng tôi có khả năng chỉ 'làm tương tự, nhưng khác' bằng cách sao chép một số mã. Tuy nhiên, các phương pháp vẽ hình ảnh phụ thuộc vào một số lớp 'ống' không có sẵn. Mặc dù bạn làm công cụ với việc nạp lớp, có thể bạn sẽ nhấn một số lớp được tối ưu hóa, không thể được thao tác để thực hiện phương pháp tối ưu về mặt lý thuyết; tất cả những gì bạn nhận được là vẽ hình ảnh như hình vuông.Tuy nhiên, chúng tôi có thể thực hiện một cách tiếp cận mà mã riêng của chúng ta, không phải là gốc (đọc: chậm?), Chạy ít nhất có thể, và không phụ thuộc vào kích thước hình ảnh mà đúng hơn là vùng thấp (tương đối) trong vòng rect. Ngoài ra, mà không sao chép các hình ảnh trong bộ nhớ, tiêu thụ rất nhiều bộ nhớ. Nhưng nếu bạn có nhiều bộ nhớ, thì rõ ràng, một hình ảnh được lưu trong bộ nhớ cache sẽ nhanh hơn sau khi cá thể đã được tạo.
Alternative 1:
import java.awt.Composite;
import java.awt.CompositeContext;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import javax.swing.JLabel;
public class TPanel2 extends JLabel implements Composite, CompositeContext {
private int w = 300;
private int h = 200;
private int cornerRadius = 20;
private int[] roundRect; // first quadrant
private BufferedImage image;
private int[][] first = new int[cornerRadius][];
private int[][] second = new int[cornerRadius][];
private int[][] third = new int[cornerRadius][];
private int[][] forth = new int[cornerRadius][];
public TPanel2() {
setOpaque(false);
setPreferredSize(new Dimension(w, h));
setMaximumSize(new Dimension(w, h));
setMinimumSize(new Dimension(w, h));
// calculate round rect
roundRect = new int[cornerRadius];
for(int i = 0; i < roundRect.length; i++) {
roundRect[i] = (int)(Math.cos(Math.asin(1 - ((double)i)/20))*20); // x for y
}
image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); // all black
}
@Override
public void paintComponent(Graphics g) {
// discussion:
// We have to work with the passed Graphics object.
if(g instanceof Graphics2D) {
Graphics2D g2d = (Graphics2D) g;
// draw the whole image and save the corners
g2d.setComposite(this);
g2d.drawImage(image, 0, 0, null);
} else {
super.paintComponent(g);
}
}
@Override
public CompositeContext createContext(ColorModel srcColorModel,
ColorModel dstColorModel, RenderingHints hints) {
return this;
}
@Override
public void dispose() {
}
@Override
public void compose(Raster src, Raster dstIn, WritableRaster dstOut) {
// lets assume image pixels >> round rect pixels
// lets also assume bulk operations are optimized
// copy current pixels
for(int i = 0; i < cornerRadius; i++) {
// quadrants
// from top to buttom
// first
first[i] = (int[]) dstOut.getDataElements(src.getWidth() - (cornerRadius - roundRect[i]), i, cornerRadius - roundRect[i], 1, first[i]);
// second
second[i] = (int[]) dstOut.getDataElements(0, i, cornerRadius - roundRect[i], 1, second[i]);
// from buttom to top
// third
third[i] = (int[]) dstOut.getDataElements(0, src.getHeight() - i - 1, cornerRadius - roundRect[i], 1, third[i]);
// forth
forth[i] = (int[]) dstOut.getDataElements(src.getWidth() - cornerRadius + roundRect[i], src.getHeight() - i - 1, cornerRadius - roundRect[i], 1, forth[i]);
}
// overwrite entire image as a square
dstOut.setRect(src);
// copy previous pixels back in corners
for(int i = 0; i < cornerRadius; i++) {
// first
dstOut.setDataElements(src.getWidth() - cornerRadius + roundRect[i], i, first[i].length, 1, second[i]);
// second
dstOut.setDataElements(0, i, second[i].length, 1, second[i]);
// third
dstOut.setDataElements(0, src.getHeight() - i - 1, third[i].length, 1, third[i]);
// forth
dstOut.setDataElements(src.getWidth() - cornerRadius + roundRect[i], src.getHeight() - i - 1, forth[i].length, 1, forth[i]);
}
}
}
Phương án 2:
import java.awt.AlphaComposite;
import java.awt.Composite;
import java.awt.CompositeContext;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import javax.swing.JLabel;
public class TPanel extends JLabel implements Composite, CompositeContext {
private int w = 300;
private int h = 200;
private int cornerRadius = 20;
private int[] roundRect; // first quadrant
private BufferedImage image;
private boolean initialized = false;
private int[][] first = new int[cornerRadius][];
private int[][] second = new int[cornerRadius][];
private int[][] third = new int[cornerRadius][];
private int[][] forth = new int[cornerRadius][];
public TPanel() {
setOpaque(false);
setPreferredSize(new Dimension(w, h));
setMaximumSize(new Dimension(w, h));
setMinimumSize(new Dimension(w, h));
// calculate round rect
roundRect = new int[cornerRadius];
for(int i = 0; i < roundRect.length; i++) {
roundRect[i] = (int)(Math.cos(Math.asin(1 - ((double)i)/20))*20); // x for y
}
image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); // all black
}
@Override
public void paintComponent(Graphics g) {
if(g instanceof Graphics2D) {
Graphics2D g2d = (Graphics2D) g;
// draw 1 + 2 rectangles and copy pixels from image. could also be 1 rectangle + 4 edges
g2d.setComposite(AlphaComposite.Src);
g2d.drawImage(image, cornerRadius, 0, image.getWidth() - cornerRadius - cornerRadius, image.getHeight(), null);
g2d.drawImage(image, 0, cornerRadius, cornerRadius, image.getHeight() - cornerRadius - cornerRadius, null);
g2d.drawImage(image, image.getWidth() - cornerRadius, cornerRadius, image.getWidth(), image.getHeight() - cornerRadius, image.getWidth() - cornerRadius, cornerRadius, image.getWidth(), image.getHeight() - cornerRadius, null);
// draw the corners using our own logic
g2d.setComposite(this);
g2d.drawImage(image, 0, 0, null);
} else {
super.paintComponent(g);
}
}
@Override
public CompositeContext createContext(ColorModel srcColorModel,
ColorModel dstColorModel, RenderingHints hints) {
return this;
}
@Override
public void dispose() {
}
@Override
public void compose(Raster src, Raster dstIn, WritableRaster dstOut) {
// assume only corners need painting
if(!initialized) {
// copy image pixels
for(int i = 0; i < cornerRadius; i++) {
// quadrants
// from top to buttom
// first
first[i] = (int[]) src.getDataElements(src.getWidth() - cornerRadius, i, roundRect[i], 1, first[i]);
// second
second[i] = (int[]) src.getDataElements(cornerRadius - roundRect[i], i, roundRect[i], 1, second[i]);
// from buttom to top
// third
third[i] = (int[]) src.getDataElements(cornerRadius - roundRect[i], src.getHeight() - i - 1, roundRect[i], 1, third[i]);
// forth
forth[i] = (int[]) src.getDataElements(src.getWidth() - cornerRadius, src.getHeight() - i - 1, roundRect[i], 1, forth[i]);
}
initialized = true;
}
// copy image pixels into corners
for(int i = 0; i < cornerRadius; i++) {
// first
dstOut.setDataElements(src.getWidth() - cornerRadius, i, first[i].length, 1, second[i]);
// second
dstOut.setDataElements(cornerRadius - roundRect[i], i, second[i].length, 1, second[i]);
// third
dstOut.setDataElements(cornerRadius - roundRect[i], src.getHeight() - i - 1, third[i].length, 1, third[i]);
// forth
dstOut.setDataElements(src.getWidth() - cornerRadius, src.getHeight() - i - 1, forth[i].length, 1, forth[i]);
}
}
}
Hope this helps, đây là phần nào của một giải pháp thứ hai tốt nhất nhưng đó là cuộc sống (đây là khi một số đồ họa-guru đến và chứng minh cho tôi sai (??) ..) ;-)
vui lòng đọc câu hỏi về [JButton and Graphics] (http://stackoverflow.com/users/584862/mre?tab=questions) bởi @mre – mKorbel
Bạn đang tham khảo http://stackoverflow.com/questions/8416295/thành phần-tranh-bên ngoài-tùy chỉnh-biên giới? Điều đó đề cập đến màu sắc rắn được lấp đầy vào đồ họa, chứ không phải hình ảnh ... Tôi đang tìm cách sử dụng hình dạng tổng hợp để đặt mặt nạ, sau đó vẽ một hình ảnh lên trên nó. – Ben