如何在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
相关产品推荐
相关产品推荐

