You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Processing中使用类嵌套?及Button类样式适配修改问询

问题分析与修复方案

你的按钮样式不生效的核心问题在于Button类内部新建了一个空的StyleCollection,而没有使用你在setupStyles()中创建的全局样式集合。这个空集合里根本没有你定义的dark/light/red/blue样式,所以sc.getStyle(getText())返回的是null,导致你只能用display方法里硬编码的默认样式(白色填充、黑色文字、15号字)。

下面是具体的修复步骤:

1. 修改Button类的构造函数,传入全局StyleCollection

我们需要让Button能够访问到全局的styles对象,所以给Button的构造函数添加一个StyleCollection参数,去掉内部新建空集合的代码:

class Button{
  private float x,y,w,h;
  private String label;
  private StyleCollection sc; // 只声明,不在构造里新建
  private Style s;

  // 修改构造函数,接收外部的StyleCollection
  public Button(float _x, float _y, StyleCollection styleCollection){
    x=_x;
    y=_y;
    w=100;
    h=75;
    sc= styleCollection; // 使用传入的全局样式集合
  }
  // ... 其他方法不变,后面修改display
}

2. 完善Button的display方法,正确应用样式

在display方法里,根据按钮的label从StyleCollection获取对应样式,如果获取不到(比如label不存在),就用默认样式兜底。然后用Style的属性设置绘图参数:

public void display(){
  // 根据按钮标签获取对应样式,没有的话用默认样式
  s = sc.getStyle(getText());
  if(s == null){
    s = sc.getDefaultStyle();
  }

  // 应用样式的背景(按钮填充)、描边
  fill(s.getBackground());
  stroke(s.getStrokeColor());
  rect(x,y,w,h);
  
  // 应用样式的文本颜色和大小
  fill(s.getFillColor());
  textSize(s.getTextSize());
  textAlign(CENTER);
  text(getText(),x+w/2,y+h/2);
}

3. 在setupButtons时传入全局styles对象

修改setupButtons()方法,创建Button实例时把全局的styles传进去:

void setupButtons(){
  for(int index=0;index<styleNames.length;index++){
    // 第三个参数传入全局的styles集合
    buttons[index] = new Button (bx, 500, styles);
    buttons[index].setLabel(styleNames[index]);
    bx=bx+150;
  }
}

修复后的完整代码

String message;
String[] styleNames={"dark","light","red","blue"};
StyleCollection styles;
Style currentStyle;
Button[] buttons= new Button[4];
float bx;

void setupButtons(){
  for(int index=0;index<styleNames.length;index++){
    buttons[index] = new Button (bx, 500, styles);
    buttons[index].setLabel(styleNames[index]);
    bx=bx+150;
  }
}

void setupStyles(){
  styles = new StyleCollection();
  Style darkStyle= new Style("dark",0,255,255,15);
  styles.addStyle(darkStyle);
  Style lightStyle= new Style("light",255,0,0,15);
  styles.addStyle(lightStyle);
  Style redStyle= new Style("red",#D69797,#FF0000,#FF0000,15);
  styles.addStyle(redStyle);
  Style blueStyle= new Style("blue",#8788EA,#0000FF,#0000FF,15);
  styles.addStyle(blueStyle);
  styles.setDefaultStyle(lightStyle);
  currentStyle=styles.getDefaultStyle();
}

void setup(){
  size(800,600);
  setupStyles();
  bx=150;
  setupButtons();
  message = ("Lorem Ipsum is simply dummy text of the printing and typesetting industry. " + 
             "Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, "+ 
             "when an unknown printer took a galley of type and scrambled it to make a type "+ 
             "specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, "+ 
             "remaining essentially unchanged. It was popularised in the 1960s with the release of "+ 
             "Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing "+ 
             "software like Aldus PageMaker including versions of Lorem Ipsum.");
}

void draw(){
  background(currentStyle.getBackground());
  fill(currentStyle.getFillColor());
  textSize(currentStyle.getTextSize());
  textAlign(LEFT);
  text(message,100,100, width/2,height);
  for (int i=0; i<buttons.length;i++){
    buttons[i].display();
  }
}

void mousePressed(){
  for(int i=0; i<buttons.length; i++){
    if (buttons[i].isInside(mouseX,mouseY)){
      String sw = buttons[i].getText();
      currentStyle=styles.getStyle(sw);
      // 找到匹配的按钮后直接跳出循环,不用再判断其他按钮
      break;
    }
  }
}

class Style{
  private int fillColor;
  private int strokeColor;
  private int bgColor;
  private int textSize;
  private String name;

  public Style(String nm, int bgCol, int strCol, int fC, int tSize){
    name=nm;
    bgColor=bgCol;
    strokeColor=strCol;
    fillColor=fC;
    textSize=tSize;
  }

  public String getSName(){ return name;}
  public int getBackground(){return bgColor;}
  public int getFillColor(){return fillColor;}
  public int getStrokeColor(){return strokeColor;}
  public int getTextSize(){return textSize;}
  public String toString(){return name+ " "+bgColor;}
}

import java.util.HashMap;
class StyleCollection{
  private HashMap <String,Style> styles;

  public StyleCollection(){
    styles= new HashMap <String, Style>();
  }

  public void addStyle(Style s){
    styles.put(s.getSName(),s);
  }

  public void setDefaultStyle(Style sD){
    styles.put("default", sD);
  }

  public Style getStyle(String stname){
    return styles.get(stname);
  }

  public Style getDefaultStyle(){
    return styles.get("default");
  }
}

class Button{
  private float x,y,w,h;
  private String label;
  private StyleCollection sc;
  private Style s;

  public Button(float _x, float _y, StyleCollection styleCollection){
    x=_x;
    y=_y;
    w=100;
    h=75;
    sc= styleCollection;
  }

  public void display(){
    s=sc.getStyle(getText());
    // 兜底:如果找不到对应样式,用默认样式
    if(s == null){
      s = sc.getDefaultStyle();
    }
    
    fill(s.getBackground());
    stroke(s.getStrokeColor());
    rect(x,y,w,h);
    
    fill(s.getFillColor());
    textSize(s.getTextSize());
    textAlign(CENTER);
    text(getText(),x+w/2,y+h/2);
  }

  public void setLabel(String _label){
    label=_label;
  }

  public String getText(){return label;}

  boolean isInside(float _mx, float _my){
    float mx,my;
    mx=_mx;
    my=_my;
    return (mx>x)&&(mx<x+w)&&(my>y)&&(my<y+h);
  }
}

另外,我还优化了mousePressed()方法,用循环代替重复的if-else,代码更简洁易维护。

现在运行代码,每个按钮都会根据自己的label应用对应的样式,点击按钮也能正确切换全局文本的样式了。

内容的提问来源于stack exchange,提问作者hdd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 07:50:52