所以我添加了 8 個 TextField 并想設定它們的背景顏色。我的想法是將第一個設定為紅色 (255, 0, 0),將最后一個設定為藍色 (0, 0, 255) 和 8 個(或實際上任何數字)其他漸變。我試圖弄清楚如何根據“如果'下一個'變數為0,以與前一個變數減少相同的數量增加這個變數”來解決它
所以它在每次迭代中可能看起來像:
setBackground(255, 0, 0);
setBackground(191, 63, 0);
setBackground(127, 127, 0);
...
setBackground(0, 0, 255);
現在我想嘗試將這種增加和減少的方式放入一個 for 回圈中,該回圈將迭代 n 次,其中 n 是 TextField 的數量(為簡單起見現在為 8)。任何人都知道是否有一個聰明的解決方案?
MRE:
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Apple{
public Apple(int width, int height) {
SwingUtilities.invokeLater(() -> initGUITest(width, height));
}
public void initGUITest(int width, int height) {
JFrame frame = new JFrame();
frame.setSize(width, height);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
JPanel panel = new JPanel();
GridLayout gl = new GridLayout(10, 1);
panel.setLayout(gl);
frame.add(panel);
for(int i = 0; i < 8; i ) {
JTextField jtf = new JTextField("Track " (i 1));
jtf.setBackground(new Color(255, 0, 0)); //Start color
panel.add(jtf);
}
}
public static void main(String args[]) {
Apple a = new Apple(300, 300);
}
}
uj5u.com熱心網友回復:
檢查一個值是否為零并從那里增加或減少一個值是低效的。
有兩種方法可以解決這個問題
線性
您計算一個混合值,(i/stepSize)并使用它在開始值和結束值之間進行線性插值,如下所示
intermediateColor[0]=(int)(start.getRed() (end.getRed()-start.getRed())*alpha);
intermediateColor[1]=(int)(start.getGreen() (end.getGreen()-start.getGreen())*alpha);
intermediateColor[2]=(int)(start.getBlue() (end.getBlue()-start.getBlue())*alpha);
將混合轉換為浮點數是插值作業所必需的,這是邏輯
private static void layout1(JFrame frame)
{
Color
start=Color.RED,
end=Color.BLUE;
int[] intermediateColor=new int[3];
int steps=8;
float alpha;
for(int i=0;i<=steps;i )
{
JTextField field=new JTextField(10);
alpha=((float)i/steps);
intermediateColor[0]=(int)(start.getRed() (end.getRed()-start.getRed())*alpha);
intermediateColor[1]=(int)(start.getGreen() (end.getGreen()-start.getGreen())*alpha);
intermediateColor[2]=(int)(start.getBlue() (end.getBlue()-start.getBlue())*alpha);
field.setBackground(new Color(intermediateColor[0],intermediateColor[1],intermediateColor[2]));
frame.add(field);
}
}
輸出 :

關鍵幀
一個更復雜的示例涉及使用關鍵幀,您可以根據您的 i 值動態更改起點和終點
這是關鍵幀
int[] checkPoints={0,2,4,6,8};
Color[] colors={Color.RED,Color.GREEN,Color.BLUE,Color.YELLOW,Color.MAGENTA};
這意味著什么
復選框 0->2 在紅色和綠色之間插值
復選框 3->4 在綠色和藍色之間插值
復選框 5->6 在藍色和黃色之間插值
復選框 7->8 在黃色和洋紅色之間插值
邏輯就在這段代碼中
//loop through all checkpoints
for(int j=0;j<checkPoints.length-1;j )
{
//check if i lies in between these 2 checkpoints
if(i>=checkPoints[j] && i<=checkPoints[j 1])
{
//interpolate between this & the next checkpoint
checkPoint=j;
start=colors[checkPoint];
end=colors[checkPoint 1];
//distance of i from start checkpoint/ total distance between checkpoints
alpha=(float)(i-checkPoints[checkPoint])/(checkPoints[checkPoint 1]-checkPoints[checkPoint]);
}
}
這是完整的代碼
public class Test
{
public static void main(String[] args)
{
JFrame frame=new JFrame("TEST");
frame.setContentPane(new JPanel(new FlowLayout(FlowLayout.LEADING,10,0)));
layout2(frame);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private static void layout1(JFrame frame)
{
Color
start=Color.RED,
end=Color.BLUE;
int[] intermediateColor=new int[3];
int steps=8;
float alpha;
for(int i=0;i<=steps;i )
{
JTextField field=new JTextField(10);
alpha=((float)i/steps);
intermediateColor[0]=(int)(start.getRed() (end.getRed()-start.getRed())*alpha);
intermediateColor[1]=(int)(start.getGreen() (end.getGreen()-start.getGreen())*alpha);
intermediateColor[2]=(int)(start.getBlue() (end.getBlue()-start.getBlue())*alpha);
field.setBackground(new Color(intermediateColor[0],intermediateColor[1],intermediateColor[2]));
frame.add(field);
}
}
private static void layout2(JFrame frame)
{
int[] checkPoints={0,2,4,6,8};
Color[] colors={Color.RED,Color.GREEN,Color.BLUE,Color.YELLOW,Color.MAGENTA};
int[] intermediateColor=new int[3];
int steps=8;
int checkPoint;
float alpha=0;
Color start=null,end=null;
for(int i=0;i<=steps;i )
{
JTextField field=new JTextField(10);
for(int j=0;j<checkPoints.length-1;j )
{
if(i>=checkPoints[j] && i<=checkPoints[j 1])
{
checkPoint=j;
start=colors[checkPoint];
end=colors[checkPoint 1];
alpha=(float)(i-checkPoints[checkPoint])/(checkPoints[checkPoint 1]-checkPoints[checkPoint]);
}
}
intermediateColor[0]=(int)(start.getRed() (end.getRed()-start.getRed())*alpha);
intermediateColor[1]=(int)(start.getGreen() (end.getGreen()-start.getGreen())*alpha);
intermediateColor[2]=(int)(start.getBlue() (end.getBlue()-start.getBlue())*alpha);
field.setBackground(new Color(intermediateColor[0],intermediateColor[1],intermediateColor[2]));
frame.add(field);
}
}
}
輸出 :

uj5u.com熱心網友回復:
所以,你可以通過多種方式做到這一點,但就我個人而言,我希望使用某種“混合”演算法,它可以讓你建立你想要的顏色“范圍”,然后基于一些價值(即指數或百分比),生成混合這些顏色(在范圍內)的顏色。
例如...

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.text.NumberFormat;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
ColorBlender blender = new ColorBlender(new float[] {0, 1}, new Color[] {Color.RED, Color.BLUE});
for (int index = 0; index < 8; index ) {
Color color = blender.blendedColorAt(index / 7f);
System.out.println(color);
JTextField textField = new JTextField(10);
textField.setBackground(color);
add(textField, gbc);
}
}
}
public class ColorBlender {
private float[] fractions;
private Color[] colors;
public ColorBlender(float[] fractions, Color[] colors) {
this.fractions = fractions;
this.colors = colors;
}
public Color blendedColorAt(float progress) {
Color color = null;
if (fractions != null) {
if (colors != null) {
if (fractions.length == colors.length) {
int[] indicies = getFractionIndicies(fractions, progress);
float[] range = new float[]{fractions[indicies[0]], fractions[indicies[1]]};
Color[] colorRange = new Color[]{colors[indicies[0]], colors[indicies[1]]};
float max = range[1] - range[0];
float value = progress - range[0];
float weight = value / max;
color = blend(colorRange[0], colorRange[1], 1f - weight);
} else {
throw new IllegalArgumentException("Fractions and colours must have equal number of elements");
}
} else {
throw new IllegalArgumentException("Colours can't be null");
}
} else {
throw new IllegalArgumentException("Fractions can't be null");
}
return color;
}
protected int[] getFractionIndicies(float[] fractions, float progress) {
int[] range = new int[2];
int startPoint = 0;
while (startPoint < fractions.length && fractions[startPoint] <= progress) {
startPoint ;
}
if (startPoint >= fractions.length) {
startPoint = fractions.length - 1;
}
range[0] = startPoint - 1;
range[1] = startPoint;
return range;
}
protected Color blend(Color color1, Color color2, double ratio) {
float r = (float) ratio;
float ir = (float) 1.0 - r;
float rgb1[] = new float[3];
float rgb2[] = new float[3];
color1.getColorComponents(rgb1);
color2.getColorComponents(rgb2);
float red = rgb1[0] * r rgb2[0] * ir;
float green = rgb1[1] * r rgb2[1] * ir;
float blue = rgb1[2] * r rgb2[2] * ir;
if (red < 0) {
red = 0;
} else if (red > 255) {
red = 255;
}
if (green < 0) {
green = 0;
} else if (green > 255) {
green = 255;
}
if (blue < 0) {
blue = 0;
} else if (blue > 255) {
blue = 255;
}
Color color = null;
try {
color = new Color(red, green, blue);
} catch (IllegalArgumentException exp) {
NumberFormat nf = NumberFormat.getNumberInstance();
System.out.println(nf.format(red) "; " nf.format(green) "; " nf.format(blue));
exp.printStackTrace();
}
return color;
}
}
}
好的,但我想混合三種顏色
好吧,不是問題。只需添加另一個“停止”和該停止的顏色,例如...
ColorBlender blender = new ColorBlender(new float[] {0f, 0.5f, 1f}, new Color[] {Color.RED, Color.YELLOW, Color.BLUE});
會產生...

想要添加更多欄位?不用擔心,只需將其更改Color color = blender.blendedColorAt(index / 7f);為7f預期欄位的數量 - 1(請記住,我們從index??0開始)
uj5u.com熱心網友回復:
這是一個可以生成一系列顏色的類,這些顏色可以在給定數量的步驟中從一種顏色過渡到另一種顏色。
簡單的用法是:
ColorTransition ct = new ColorTransition(Color.RED, Color.BLUE, 8);
如果您需要多個轉換,您可以執行以下操作:
ColorTransition ct = new ColorTransition(Color.RED, Color.BLUE, 8);
ct.transitionTo(Color.GREEN, 4);
然后將從藍色過渡到綠色。
生成所有過渡顏色后,您可以單獨訪問它們:
import java.awt.*;
import javax.swing.*;
import java.util.*;
public class ColorTransition
{
private ArrayList<Color> colors;
public ColorTransition(Color startColor, Color endColor, int steps)
{
colors = new ArrayList<>(steps);
colors.add( startColor );
transitionTo(endColor, steps);
}
public void transitionTo(Color endColor, int steps)
{
Color startColor = colors.get(colors.size() - 1);
float rDelta = endColor.getRed() - startColor.getRed();
float gDelta = endColor.getGreen() - startColor.getGreen();
float bDelta = endColor.getBlue() - startColor.getBlue();
for (int i = 1; i < steps; i )
{
float stepIncrement = (float)i / (steps - 1);
int rValue = (int)(startColor.getRed() (rDelta * stepIncrement));
int gValue = (int)(startColor.getGreen() (gDelta * stepIncrement));
int bValue = (int)(startColor.getBlue() (bDelta * stepIncrement));
Color color = new Color(rValue, gValue, bValue);
colors.add( color );
}
}
public int size()
{
return colors.size();
}
public Color getColorAt(int index)
{
return colors.get( index );
}
private static void createAndShowGUI()
{
ColorTransition ct = new ColorTransition(Color.RED, Color.BLUE, 8);
// ct.transitionTo(Color.GREEN, 4);
JPanel panel = new JPanel( new GridLayout(0, 1) );
for (int i = 0; i < ct.size(); i )
{
JTextField textField = new JTextField(25);
textField.setBackground( ct.getColorAt(i) );
panel.add( textField );
}
JFrame frame = new JFrame("Color Transition");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args) throws Exception
{
java.awt.EventQueue.invokeLater( () -> createAndShowGUI() );
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/439793.html
上一篇:JButton文本會自行更改嗎?
